Rectangle 27 3

Here's a super-simple example with basic authentication, headers, and exception handling...

private HttpHeaders createHttpHeaders(String user, String password)
{
    String notEncoded = "Basic " + user + ":" + password;
    String encodedAuth = Base64.getEncoder().encodeToString(notEncoded.getBytes());
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    headers.add("Authorization", encodedAuth);
    return headers;
}

private void doYourThing() 
{
    String theUrl = "http://blah.blah.com:8080/rest/api/blah";
    RestTemplate restTemplate = new RestTemplate();
    try {
        HttpHeaders headers = createHttpHeaders("fred","1234");
        HttpEntity<String> entity = new HttpEntity<String>("parameters", headers);
        ResponseEntity<String> response = restTemplate.exchange(theUrl, HttpMethod.GET, entity, String.class);
        System.out.println("Result - status ("+ response.getStatusCode() + ") has body: " + response.hasBody());
    }
    catch (Exception eek) {
        System.out.println("** Exception: "+ eek.getMessage());
    }
}

Not sure why this was originally downvoted. If you're the first to downvote, feel free to explain in a comment.

The "Basic " part should not be encoded, should it be ?

I also just discovered that "Basic" shouldn't be encoded as well. This is a good example of how to do auth that I myself used, but correcting the encoding would be good.

java - Sending GET request with Authentication headers using restTempl...

java spring spring-mvc resttemplate
Rectangle 27 3

You might want to try different Tomcat versions.

You are missing dependencies.

<properties>
    <spring.version>3.0.1.RELEASE</spring.version>
</properties>
<dependency>
    <groupId>org.springframework.security</groupId>
     <artifactId>spring-security-web</artifactId>
     <version>${spring.version}</version>
</dependency>
<dependency>
     <groupId>org.springframework.security</groupId>
     <artifactId>spring-security-config</artifactId>
     <version>${spring.version}</version>
</dependency>
<dependency>
     <groupId>org.springframework.security</groupId>
     <artifactId>spring-security-taglibs</artifactId>
     <version>${spring.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-core</artifactId>
    <version>${spring.version}</version>
</dependency>

You don't seem to be using maven so this site will help you find the jars you need. Just search for the <artifactId> and you will be able to download the .jar for the dependency.

This HOWTO might help you on a minimal spring-security configuration.

I have added all of those jars in the past and I received the same error, which is why I tried to use Spring 2.5.6 instead, since it only has one jar file as a dependency. I attempted again with your solution and the error remains the same. I have added the jars and then added them to the class path.

Hmm, the missing class is usually found in the servlet.jar, have you tried deploying something else on this exact server ?

@Simeon I am unsure what you mean by servlet.jar. I have never dealt with that particular jar file. As for your second question I have deployed this exact web service sans Spring Security just fine. It is only when I add the Spring Security that I have problems.

@SC the servlet.jar (or servlet-api.jar) is the jar that contains the class javax/servlet/ServletContextListener. It should be in your /commons/lib folder in Tomcat. It might be some ClassLoader related Tomcat/Spring issue you can try a different Tomcat version and if it works you would have found a bug IMO.

java - Cannot integrate Spring Security BASIC Authentication into Jers...

java spring-security jersey basic-authentication
Rectangle 27 7

I was recently dealing with an issue when I was trying to get past authentication while making a REST call from Java, and while the answers in this thread (and other threads) helped, there was still a bit of trial and error involved in getting it working.

What worked for me was encoding credentials in Base64 and adding them as Basic Authorization headers. I then added them as an HttpEntity to restTemplate.postForEntity, which gave me the response I needed.

Here's the class I wrote for this in full (extending RestTemplate):

public class AuthorizedRestTemplate extends RestTemplate{

    private String username;
    private String password;

    public AuthorizedRestTemplate(String username, String password){
        this.username = username;
        this.password = password;
    }

    public String getForObject(String url, Object... urlVariables){
        return authorizedRestCall(this, url, urlVariables);
    }

    private String authorizedRestCall(RestTemplate restTemplate, 
            String url, Object... urlVariables){
        HttpEntity<String> request = getRequest();
        ResponseEntity<String> entity = restTemplate.postForEntity(url, 
                request, String.class, urlVariables);
        return entity.getBody();
    }

    private HttpEntity<String> getRequest(){
        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization", "Basic " + getBase64Credentials());
        return new HttpEntity<String>(headers);
    }

    private String getBase64Credentials(){
        String plainCreds = username + ":" + password;
        byte[] plainCredsBytes = plainCreds.getBytes();
        byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes);
        return new String(base64CredsBytes);
    }
}

java - Making authenticated POST requests with Spring RestTemplate for...

java android spring rest resttemplate
Rectangle 27 32

You're not missing anything. RestTemplate#exchange(..) is the appropriate method to use to set request headers.

Here's an example (with POST, but just change that to GET and use the entity you want).

Note that with a GET, your request entity doesn't have to contain anything (unless your API expects it, but that would go against the HTTP spec). It can be an empty String.

java - Sending GET request with Authentication headers using restTempl...

java spring spring-mvc resttemplate
Rectangle 27 32

I'm sucessfully using spring security for securing my Jersey-based API. It has pluggable authentication schemes allowing you to switch from Basic Auth to something else later. I'm not using Spring in general, just the security stuff.

Here is the relevant part from my web.xml

<listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
        /WEB-INF/security-applicationContext.xml,
        /WEB-INF/applicationContext.xml
    </param-value>
</context-param>

<!-- Enables Spring Security -->

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>
        org.springframework.web.filter.DelegatingFilterProxy
    </filter-class>
    <init-param>
        <param-name>targetBeanName</param-name>
        <param-value>springSecurityFilterChain</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>

</filter-mapping>

You can leave applicationContext.xml empty (<beans></beans>). An example of the security-applicationContext.xml can be found here

I have replaced the dead snippet with a gist containing an example security-applicationContext.xml

java - User authentication on a Jersey REST service - Stack Overflow

java http authentication jersey
Rectangle 27 10

Spring security does support both basic authentication and form based authentication (embedding the username/password in the URL).

A REST service is generally authenticated on each and every request, not normally by a session. The default spring security authentication (assuming you're on 3.x) should look for basic authentication parameters or form parameters (j_username and j_password) (in the form http://you.com/rest_service?j_username=xyz&j_password=abc).

Manually tacking the j_username/j_password onto the URL, adding them as post parameters (I believe), or setting the basic authentication username/password should all work to authenticate a REST service against the default Spring Security interceptors, right out of the box.

I will admit that I haven't tried this on REST services, though I do clearly recall reading exactly this in the docs as I did the same for basic page logins on spring security recently. Disclaimer over.

Thanks a lot for the answer, this was close (the ideas helped a lot) but didn't work out of the box - I made a post on what it took to get it working: storypodders.com/dasBlog/2011/01/22/

That was a great post, thanks for contributing it, I'm certain it will be found and useful to many others.

Putting username and password in the URL is usually considered a bad idea. Webserver log files often contain query parameters which would expose your credentials. Anyone accessing your RESTful service from a browser would have credentials exposed in their history.

java - Calling a REST web service secured with Spring Security from An...

java web-services spring rest spring-security
Rectangle 27 21

You can use postForObject with an HttpEntity. It would look like this:

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.set("Authorization", "Bearer "+accessToken);

HttpEntity<String> entity = new HttpEntity<String>(requestJson,headers);
String result = restTemplate.postForObject(url, entity, String.class);

In a GET request, you'd usually not send a body (it's allowed, but it doesn't serve any purpose). The way to add headers without wiring the RestTemplate differently is to use the exchange or execute methods directly. The get shorthands don't support header modification.

The asymmetry is a bit weird on a first glance, perhaps this is going to be fixed in future versions of Spring.

restTemplate.postForEntity(url, entity, String.class)

java - Sending GET request with Authentication headers using restTempl...

java spring spring-mvc resttemplate
Rectangle 27 4

If, like me, you struggled to find an example that uses headers with basic authentication and the rest template exchange API, this is what I finally worked out...

private HttpHeaders createHttpHeaders(String user, String password)
{
    String notEncoded = user + ":" + password;
    String encodedAuth = Base64.getEncoder().encodeToString(notEncoded.getBytes());
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.APPLICATION_JSON);
    headers.add("Authorization", "Basic " + encodedAuth);
    return headers;
}

private void doYourThing() 
{
    String theUrl = "http://blah.blah.com:8080/rest/api/blah";
    RestTemplate restTemplate = new RestTemplate();
    try {
        HttpHeaders headers = createHttpHeaders("fred","1234");
        HttpEntity<String> entity = new HttpEntity<String>("parameters", headers);
        ResponseEntity<String> response = restTemplate.exchange(theUrl, HttpMethod.GET, entity, String.class);
        System.out.println("Result - status ("+ response.getStatusCode() + ") has body: " + response.hasBody());
    }
    catch (Exception eek) {
        System.out.println("** Exception: "+ eek.getMessage());
    }
}

rest - How to set an "Accept:" header on Spring RestTemplate request? ...

spring rest resttemplate
Rectangle 27 3

For Spring Security version 4, the default login processing URL is:

http://localhost:8080/myApp/login
j_spring_security_check

java - Spring Security Rest Basic authentication - Stack Overflow

java spring spring-security
Rectangle 27 2

In Spring 4 form field default names were changed from j_username and j_password to username and password. You should either change it in your request or explicitly set it in your xml config. Also login-processing-url default changed from j_spring_security_check to login. Here you can find some info about it.

java - Spring Security Rest Basic authentication - Stack Overflow

java spring spring-security
Rectangle 27 13

You are getting the exception because none of RestTemplate's default MessageConverters know how to serialize the InputStream contained by the MultipartFile file. When sending objects via RestTemplate, in most cases you want to send POJOs. You can fix this by adding the bytes of the MultipartFile to the MultiValueMap instead of the MultipartFile itself.

File file1 = (File) req.getAttribute("userfile1");

should always return null, as ServletRequest's getAttribute method does not return request/form parameters but attributes set by the servlet context. Are you sure it is actually working with your curl example?

Here is an example of a Spring MVC method forwarding a file to a servlet:

Servlet (though I tested it running in a Spring MVC container), adapted from here:

@RequestMapping("/pi")
private void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

  final String path = request.getParameter("destination");
  final Part filePart = request.getPart("file");
  final String fileName = request.getParameter("filename");

  OutputStream out = null;
  InputStream fileContent = null;
  final PrintWriter writer = response.getWriter();

  try {
    out = new FileOutputStream(new File(path + File.separator
            + fileName));
    fileContent = filePart.getInputStream();

    int read = 0;
    final byte[] bytes = new byte[1024];

    while ((read = fileContent.read(bytes)) != -1) {
      out.write(bytes, 0, read);
    }
    writer.println("New file " + fileName + " created at " + path);

  } catch (FileNotFoundException fne) {
    writer.println("You either did not specify a file to upload or are "
            + "trying to upload a file to a protected or nonexistent "
            + "location.");
    writer.println("<br/> ERROR: " + fne.getMessage());

  } finally {
    if (out != null) {
      out.close();
    }
    if (fileContent != null) {
      fileContent.close();
    }
    if (writer != null) {
      writer.close();
    }
  }
}
@ResponseBody
@RequestMapping(value="/upload/", method=RequestMethod.POST, 
        produces = "text/plain")
public String uploadFile(MultipartHttpServletRequest request) 
        throws IOException {

  Iterator<String> itr = request.getFileNames();

  MultipartFile file = request.getFile(itr.next());
  MultiValueMap<String, Object> parts = 
          new LinkedMultiValueMap<String, Object>();
  parts.add("file", new ByteArrayResource(file.getBytes()));
  parts.add("filename", file.getOriginalFilename());

  RestTemplate restTemplate = new RestTemplate();
  HttpHeaders headers = new HttpHeaders();
  headers.setContentType(MediaType.MULTIPART_FORM_DATA);

  HttpEntity<MultiValueMap<String, Object>> requestEntity =
          new HttpEntity<MultiValueMap<String, Object>>(parts, headers);

  // file upload path on destination server
  parts.add("destination", "./");

  ResponseEntity<String> response =
          restTemplate.exchange("http://localhost:8080/pi", 
                  HttpMethod.POST, requestEntity, String.class);

  if (response != null && !response.getBody().trim().equals("")) {
    return response.getBody();
  }

  return "error";
}

Using these I can succesfully upload a file through the MVC method to the servlet by the following curl:

curl --form file=@test.dat localhost:8080/upload/

java - How to send Multipart form data with restTemplate Spring-mvc - ...

java spring post multipartform-data resttemplate
Rectangle 27 1

  • Should i have only have Basic Authentication.

You must use standard authentication method with application username and password.

  • I want user to be authenticated using Login page since for user of my web application i cant ask them to use basic authentication? How can i overcome this

Yes you can accept user credentials from login page and authenticate at server side using REST services.

  • Should i disable session in spring ?

Each HTTP RESTful request is a stateless request. Session are irrelevant in RESTful. You need to pass username/password and token with each request to identify particular user.

  • For web application users for every subsequent request do they have to pass credentials in request headers?

Not needed. You can accept username/password only in first request, authenticate and provide unique token to client. This token then would be sent to server for each subsequent request to identify user on server. You can set expiration time for the token.

java - Spring Security Rest web application and Spring Security - Stac...

java spring rest spring-mvc spring-security
Rectangle 27 67

Ok found the answer. exchange() is the best way. Oddly the HttpEntity class doesn't have a setBody() method (it has getBody()), but it is still possible to set the request body, via the constructor.

// Create the request body as a MultiValueMap
MultiValueMap<String, String> body = new LinkedMultiValueMap<String, String>();     

body.add("field", "value");

// Note the body object as first parameter!
HttpEntity<?> httpEntity = new HttpEntity<Object>(body, requestHeaders);

MyModel model = restTemplate.exchange("/api/url", HttpMethod.POST, httpEntity, MyModel.class);

It throws a TypeMismatch error Type mismatch: cannot convert from ResponseEntity<MyModel> to MyModel .. I guess it should be ResponseEntity<MyModel> model = restTemplate.exchange("/api/url", HttpMethod.POST, httpEntity, MyModel.class);

MyModel myModel = restTemplate.exchange(completeServiceUrl, HttpMethod.GET, request, MyModel.class).getBody()

java - Making authenticated POST requests with Spring RestTemplate for...

java android spring rest resttemplate
Rectangle 27 1

login
filterProcessesUrl
UsernamePasswordAuthenticationFilter
username
password
  • password-parameter The name of the request parameter which contains the password. Defaults to "password".
  • username-parameter The name of the request parameter which contains the username. Defaults to "username".
POST

Defines whether only HTTP POST requests will be allowed by this filter. If set to true, and an authentication request is received which is not a POST request, an exception will be raised immediately and authentication will not be attempted. The unsuccessfulAuthentication() method will be called as if handling a failed authentication. Defaults to true but may be overridden by subclasses.

form-login

If you want to use basic authentication instead of form login, then change the configuration to

<http use-expressions="false">
    <intercept-url pattern="/**" access="ROLE_USER" />
    <http-basic />
</http>

Basic authentication will then take precedence and will be used to prompt for a login when a user attempts to access a protected resource. Form login is still available in this configuration if you wish to use it, for example through a login form embedded in another web page.

Thanks, I don't want to use Basic Authentication, I'm configuring spring security for a REST application. when I try to authenticate using a POST it gives me a 401 code status. I know what is the difference between basic authentication and form login.

java - Spring Security Rest Basic authentication - Stack Overflow

java spring spring-security
Rectangle 27 10

I believe you should probably look at the ResponseExtractor interface & call execute on the RestTemplate providing your implementation of the extractor. To me it looks like a common requirement to do this so have logged this:

private class MyResponseExtractor extends HttpMessageConverterExtractor<MyEntity> {

    public MyResponseExtractor (Class<MyEntity> responseType,
      List<HttpMessageConverter<?>> messageConverters) {
        super(responseType, messageConverters);
    }

    @Override
    public MyEntity extractData(ClientHttpResponse response) throws IOException {

        MyEntity result;

        if (response.getStatusCode() == HttpStatus.OK) {
            result = super.extractData(response);
        } else {
            result = null;
        }

        return result;
    }
}

To create the instance of the ResponseExtractor I call the constructor & pass the converters from a RestTemplate instance that's been injected;

ResponseExtractor<MyEntity> responseExtractor =
    new MyResponseExtractor(MyEntity.class, restTemplate.getMessageConverters());

Then the call is:

MyEntity responseAsEntity =
    restTemplate.execute(urlToCall, HttpMethod.GET, null, responseExtractor);

This could be even more generic if you replace MyEnttity by a generic

java - Spring RestTemplate Behavior when handling responses with a sta...

java web-services unit-testing rest spring-mvc
Rectangle 27 40

The following does what you need (CustomAuthenticationProvider is your implementation which needs to be managed by Spring)

@Configuration
@EnableWebMvcSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private CustomAuthenticationProvider customAuthenticationProvider;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        /**
         * Do your stuff here
         */
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(customAuthenticationProvider);
    }
}

Is it possible to register a custom authentication provider in addition to the existing ones?

@Seppl I dont think that something like that exists out of the box (although I could easily be mistaked), but I'm pretty sure that something like that could be implemented relatively easily. Check out this

According to the Spring Docu, auth.authenticationProvider() will "Add authentication based upon the custom AuthenticationProvider that is passed in." I'd guess that you get a stack of providers in this way.

Custom Authentication provider with Spring Security and Java Config - ...

spring spring-security spring-java-config
Rectangle 27 1

You could use form-based login for logging in with browser and http basic authentication for login for REST endpoints. For xml configuration, that would be and respectively.

Can you suggest me the corrections necessary in the code from main post to achieve that.

Rest is really for automated transfer of data and when you show a computer ui elements including forms and expect them to fill it out its bloat at best

java - Spring Security : Testing & understanding REST authentication -...

java spring rest spring-mvc spring-security
Rectangle 27 1

All of these answers appear to be incomplete and/or kludges. Looking at the RestTemplate interface, it sure looks like it is intended to have a ClientHttpRequestFactory injected into it, and then that requestFactory will be used to create the request, including any customizations of headers, body, and request params.

ClientHttpRequestFactory
RestTemplate
new RestTemplate(myHttpRequestFactory)

Unfortunately, it looks somewhat non-trivial to create such a factory, even when you just want to set a single Authorization header, which is pretty frustrating considering what a common requirement that likely is, but at least it allows easy use if, for example, your Authorization header can be created from data contained in a Spring-Security Authorization object, then you can create a factory that sets the outgoing AuthorizationHeader on every request by doing SecurityContextHolder.getContext().getAuthorization() and then populating the header, with null checks as appropriate. Now all outbound rest calls made with that RestTemplate will have the correct Authorization header.

Without more emphasis placed on the HttpClientFactory mechanism, providing simple-to-overload base classes for common cases like adding a single header to requests, most of the nice convenience methods of RestTemplate end up being a waste of time, since they can only rarely be used.

I'd like to see something simple like this made available

@Configuration
public class MyConfig {
  @Bean
  public RestTemplate getRestTemplate() {
    return new RestTemplate(new AbstractHeaderRewritingHttpClientFactory() {
        @Override
        public HttpHeaders modifyHeaders(HttpHeaders headers) {
          headers.addHeader("Authorization", computeAuthString());
          return headers;
        }
        public String computeAuthString() {
          // do something better than this, but you get the idea
          return SecurityContextHolder.getContext().getAuthorization().getCredential();
        }
    });
  }
}

At the moment, the interface of the available ClientHttpRequestFactory's are harder to interact with than that. Even better would be an abstract wrapper for existing factory implementations which makes them look like a simpler object like AbstractHeaderRewritingRequestFactory for the purposes of replacing just that one piece of functionality. Right now, they are very general purpose such that even writing those wrappers is a complex piece of research.

java - Sending GET request with Authentication headers using restTempl...

java spring spring-mvc resttemplate
Rectangle 27 10

MultiValueMap<String, String> headers = new LinkedMultiValueMap<String, String>();
headers.add("HeaderName", "value");
headers.add("Content-Type", "application/json");

RestTemplate restTemplate = new RestTemplate();
restTemplate.getMessageConverters().add(new MappingJackson2HttpMessageConverter());

HttpEntity<ObjectToPass> request = new HttpEntity<ObjectToPass>(objectToPass, headers);

restTemplate.postForObject(url, request, ClassWhateverYourControllerReturns.class);

@Ismail Iqbal - it can be any object with info you need to pass (for example private Person john = Person("John", 24);). It will be converted to json payload and sent to the server via request body

java - Making authenticated POST requests with Spring RestTemplate for...

java android spring rest resttemplate
Rectangle 27 1

REST is stateless. With that in mind, are you looking to still have authentication/authorization for the services in a RESTful fashion? To do this, you will have to authenticate the user on EVERY call. You can use Basic authentication to stick to strict REST principles or you can violate REST slightly by using OAuth yourself.

You can do anything you want with HTTP. REST is just a group of PRINCIPALS on implementing a HTTP API.

java - Spring Security 3 Web + Restful Login - Stack Overflow

java spring rest spring-mvc spring-security