Rectangle 27 1

The $resource configuration object is very similar to the $http configuration object (with a few changes). The value of the object, the action, is the name of the method on the resource object

angular.module('myApp', ['ngResource'])
    .factory('UserService', [
        '$resource', function($resource) {
            return $resource('/api/users/:id', {
                id: '@'
            }, {
                query: {
                    method: 'PUT', // or something else 
                    headers:{'Authorization': 'Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=='} 
                }
            });
        }]);

This is not what I'm looking for, I'm looking for how to do a query with $resource. What should the method be? GET? And where should I put the credentials? Username and password?

its a simple http auth using basic. I want to add for example this to the header: 'Authorization: Basic aHR0cHdhdGNoOmY='

I've updated example, I hope that should work , if not please try {'Authorization Basic': 'QWxhZGRpbjpvcGVuIHNlc2FtZQ=='}

thanks, looks like a bug in chrome. works in firefox.

rest - AngularJS $resource request, withCredentials with username and ...

angularjs rest http ngresource
Rectangle 27 951

What you can do with JAX-RS 2.0 (Jersey, RESTEasy and Apache CXF)

In token-based authentication, the client exchanges hard credentials (such as username and password) for a piece of data called token. For each request, instead of sending the hard credentials, the client will send the token to the server to perform authentication and then authorization.

In a few words, an authentication scheme based on tokens follow these steps:

  • The client sends their credentials (username and password) to the server.
  • The server authenticates the credentials and, if they are valid, generate a token for the user.
  • The server stores the previously generated token in some storage along with the user identifier and an expiration date.
  • The server sends the generated token to the client.
  • The client sends the token to the server in each request.
  • If the token is valid, the server accepts the request.
  • If the token is invalid, the server refuses the request.
  • Once the authentication has been performed, the server performs authorization.
  • The server can provide an endpoint to refresh tokens.

This solution uses only the JAX-RS 2.0 API, avoiding any vendor specific solution. So, it should work with JAX-RS 2.0 implementations, such as Jersey, RESTEasy and Apache CXF.

It is worthwhile to mention that if you are using token-based authentication, you are not relying on the standard Java EE web application security mechanisms offered by the servlet container and configurable via application's web.xml descriptor. It's a custom authentication.

Create a JAX-RS resource method which receives and validates the credentials (username and password) and issue a token for the user:

@Path("/authentication")
public class AuthenticationEndpoint {

    @POST
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    public Response authenticateUser(@FormParam("username") String username, 
                                     @FormParam("password") String password) {

        try {

            // Authenticate the user using the credentials provided
            authenticate(username, password);

            // Issue a token for the user
            String token = issueToken(username);

            // Return the token on the response
            return Response.ok(token).build();

        } catch (Exception e) {
            return Response.status(Response.Status.FORBIDDEN).build();
        }      
    }

    private void authenticate(String username, String password) throws Exception {
        // Authenticate against a database, LDAP, file or whatever
        // Throw an Exception if the credentials are invalid
    }

    private String issueToken(String username) {
        // Issue a token (can be a random String persisted to a database or a JWT token)
        // The issued token must be associated to a user
        // Return the issued token
    }
}

If any exceptions are thrown when validating the credentials, a response with the status 403 (Forbidden) will be returned.

If the credentials are successfully validated, a response with the status 200 (OK) will be returned and the issued token will be sent to the client in the response payload. The client must send the token to the server in every request.

When consuming application/x-www-form-urlencoded, the client must to send the credentials in the following format in the request payload:

username=admin&password=123456

Instead of form params, it's possible to wrap the username and the password into a class:

public class Credentials implements Serializable {

    private String username;
    private String password;

    // Getters and setters omitted
}

And then consume it as JSON:

@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response authenticateUser(Credentials credentials) {

    String username = credentials.getUsername();
    String password = credentials.getPassword();

    // Authenticate the user, issue a token and return a response
}

Using this approach, the client must to send the credentials in the following format in the payload of the request:

{
  "username": "admin",
  "password": "123456"
}

The client should send the token in the standard HTTP Authorization header of the request. For example:

Authorization: Bearer <token-goes-here>

The name of the standard HTTP header is unfortunate because it carries authentication information, not authorization. However, it's the standard HTTP header for sending credentials to the server.

JAX-RS provides @NameBinding, a meta-annotation used to create other annotations to bind filters and interceptors to resource classes and methods. Define a @Secured annotation as following:

@NameBinding
@Retention(RUNTIME)
@Target({TYPE, METHOD})
public @interface Secured { }

The above defined name-binding annotation will be used to decorate a filter class, which implements ContainerRequestFilter, allowing you to intercept the request before it be handled by a resource method. The ContainerRequestContext can be used to access the HTTP request headers and then extract the token:

@Secured
@Provider
@Priority(Priorities.AUTHENTICATION)
public class AuthenticationFilter implements ContainerRequestFilter {

    private static final String REALM = "example";
    private static final String AUTHENTICATION_SCHEME = "Bearer";

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {

        // Get the Authorization header from the request
        String authorizationHeader =
                requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);

        // Validate the Authorization header
        if (!isTokenBasedAuthentication(authorizationHeader)) {
            abortWithUnauthorized(requestContext);
            return;
        }

        // Extract the token from the Authorization header
        String token = authorizationHeader
                            .substring(AUTHENTICATION_SCHEME.length()).trim();

        try {

            // Validate the token
            validateToken(token);

        } catch (Exception e) {
            abortWithUnauthorized(requestContext);
        }
    }

    private boolean isTokenBasedAuthentication(String authorizationHeader) {

        // Check if the Authorization header is valid
        // It must not be null and must be prefixed with "Bearer" plus a whitespace
        // The authentication scheme comparison must be case-insensitive
        return authorizationHeader != null && authorizationHeader.toLowerCase()
                    .startsWith(AUTHENTICATION_SCHEME.toLowerCase() + " ");
    }

    private void abortWithUnauthorized(ContainerRequestContext requestContext) {

        // Abort the filter chain with a 401 status code response
        // The WWW-Authenticate header is sent along with the response
        requestContext.abortWith(
                Response.status(Response.Status.UNAUTHORIZED)
                        .header(HttpHeaders.WWW_AUTHENTICATE, 
                                AUTHENTICATION_SCHEME + " realm=\"" + REALM + "\"")
                        .build());
    }

    private void validateToken(String token) throws Exception {
        // Check if the token was issued by the server and if it's not expired
        // Throw an Exception if the token is invalid
    }
}

If any problems happen during the token validation, a response with the status 401 (Unauthorized) will be returned. Otherwise the request will proceed to a resource method.

To bind the authentication filter to resource methods or resource classes, annotate them with the @Secured annotation created above. For the methods and/or classes that are annotated, the filter will be executed. It means that such endpoints will only be reached if the request is performed with a valid token.

If some methods or classes do not need authentication, simply do not annotate them:

@Path("/example")
public class ExampleResource {

    @GET
    @Path("{id}")
    @Produces(MediaType.APPLICATION_JSON)
    public Response myUnsecuredMethod(@PathParam("id") Long id) {
        // This method is not annotated with @Secured
        // The authentication filter won't be executed before invoking this method
        ...
    }

    @DELETE
    @Secured
    @Path("{id}")
    @Produces(MediaType.APPLICATION_JSON)
    public Response mySecuredMethod(@PathParam("id") Long id) {
        // This method is annotated with @Secured
        // The authentication filter will be executed before invoking this method
        // The HTTP request must be performed with a valid token
        ...
    }
}

In the example shown above, the filter will be executed only for the mySecuredMethod(Long) method because it's annotated with @Secured.

It's very likely that you will need to know the user who is performing the request agains your REST API. The following approaches can be used to achieve it:

Within your ContainerRequestFilter.filter(ContainerRequestContext) method, a new SecurityContext instance can be set for the current request. Then override the SecurityContext.getUserPrincipal(), returning a Principal instance:

final SecurityContext currentSecurityContext = requestContext.getSecurityContext();
requestContext.setSecurityContext(new SecurityContext() {

        @Override
        public Principal getUserPrincipal() {
            return () -> username;
        }

    @Override
    public boolean isUserInRole(String role) {
        return true;
    }

    @Override
    public boolean isSecure() {
        return currentSecurityContext.isSecure();
    }

    @Override
    public String getAuthenticationScheme() {
        return AUTHENTICATION_SCHEME;
    }
});

Use the token to look up the user identifier (username), which will be the Principal's name.

Inject the SecurityContext in any JAX-RS resource class:

@Context
SecurityContext securityContext;

The same can be done in a JAX-RS resource method:

@GET
@Secured
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response myMethod(@PathParam("id") Long id, 
                         @Context SecurityContext securityContext) {
    ...
}

And then get the Principal:

Principal principal = securityContext.getUserPrincipal();
String username = principal.getName();

If, for some reason, you don't want to override the SecurityContext, you can use CDI (Context and Dependency Injection), which provides useful features such as events and producers.

Create a CDI qualifier:

@Qualifier
@Retention(RUNTIME)
@Target({ METHOD, FIELD, PARAMETER })
public @interface AuthenticatedUser { }
AuthenticationFilter
Event
@AuthenticatedUser
@Inject
@AuthenticatedUser
Event<String> userAuthenticatedEvent;

If the authentication succeeds, fire the event passing the username as parameter (remember, the token is issued for a user and the token will be used to look up the user identifier):

userAuthenticatedEvent.fire(username);

It's very likely that there's a class that represents a user in your application. Let's call this class User.

Create a CDI bean to handle the authentication event, find a User instance with the correspondent username and assign it to the authenticatedUser producer field:

@RequestScoped
public class AuthenticatedUserProducer {

    @Produces
    @RequestScoped
    @AuthenticatedUser
    private User authenticatedUser;

    public void handleAuthenticationEvent(@Observes @AuthenticatedUser String username) {
        this.authenticatedUser = findUser(username);
    }

    private User findUser(String username) {
        // Hit the the database or a service to find a user by its username and return it
        // Return the User instance
    }
}

The authenticatedUser field produces a User instance that can be injected into container managed beans, such as JAX-RS services, CDI beans, servlets and EJBs. Use the following piece of code to inject a User instance (in fact, it's a CDI proxy):

@Inject
@AuthenticatedUser
User authenticatedUser;

Note that the CDI @Produces annotation is different from the JAX-RS @Produces annotation:

javax.enterprise.inject.Produces
javax.ws.rs.Produces

Be sure you use the CDI @Produces annotation in your AuthenticatedUserProducer bean.

The key here is the bean annotated with @RequestScoped, allowing you to share data between filters and your beans. If you don't wan't to use events, you can modify the filter to store the authenticated user in a request scoped bean and then read it from your JAX-RS resource classes.

Compared to the approach that overrides the SecurityContext, the CDI approach allows you to get the authenticated user from beans other than JAX-RS resources and providers.

A token can be:

  • Opaque: Reveals no details other than the value itself (like a random string)
  • Self-contained: Contains details about the token itself (like JWT).

A token can be issued by generating a random string and persisting it to a database along with the user identifier and an expiration date. A good example of how to generate a random string in Java can be seen here. You also could use:

Random random = new SecureRandom();
String token = new BigInteger(130, random).toString(32);

JWT (JSON Web Token) is a standard method for representing claims securely between two parties and is defined by the RFC 7519.

It's a self-contained token and it enables you to store details in claims. These claims are stored in the token payload which is a JSON encoded as Base64. Here are some claims registered in the RFC 7519 and what they mean (read the full RFC for further details):

  • iss: Principal that issued the token.
  • sub: Principal that is the subject of the JWT.
exp
nbf
  • iat: Time on which the token was issued.
jti

Be aware that you must not store sensitive data, such as passwords, in the token.

The payload can be read by the client and the integrity of the token can be easily checked by verifying its signature on the server. The signature is what prevents the token from being tampered with.

You won't need to persist JWT tokens if you don't need to track them. Althought, by persisting the tokens, you will have the possibility of invalidating and revoking the access of them. To keep the track of JWT tokens, instead of persisting the whole token on the server, you could persist the token identifier (jti claim) along with some other details such as the user you issued the token for, the expiration date, etc.

When persisting tokens, always consider removing the old ones in order to prevent your database from growing indefinitely.

There are a few Java libraries to issue and validate JWT tokens such as:

To find some other great resources to work with JWT, have a look at http://jwt.io.

Accept only valid (and non-expired) tokens for refreshment. It's responsability of the client to refresh the tokens before the expiration date indicated in the exp claim.

You should prevent the tokens from being refreshed indefinitely. See below a few approaches that you could consider.

You could keep the track of token refreshment by adding two claims to your token (the claim names are up to you):

  • refreshLimit: Indicates how many times the token can be refreshed.
  • refreshCount: Indicates how many times the token has been refreshed.

So only refresh the token if the following conditions are true:

  • The token is not expired (exp >= now).
  • The number of times that the token has been refreshed is less than the number of times that the token can be refreshed (refreshCount < refreshLimit).

And when refreshing the token:

exp = now + some-amount-of-time
  • Increment the number of times that the token has been refreshed (refreshCount++).

Alternatively to keeping the track of the number of refreshments, you could have a claim that indicates the absolute expiration date (which works pretty similar to the refreshLimit claim described above). Before the absolute expiration date, any number of refreshments is acceptable.

Another approach involves issuing a separate long-lived refresh token that is used to issue short-lived JWT tokens.

If you want to revoke tokens, you must keep the track of them. You don't need to store the whole token on server side, store only the token identifier (that must be unique) and some metadata if you need. For the token identifier you could use UUID.

The jti claim should be used to store the token identifier on the token. When validating the token, ensure that it has not been revoked by checking the value of the jti claim against the token identifiers you have on server side.

For security purposes, revoke all the tokens for a user when they change their password.

  • It doesn't matter which type of authentication you decide to use. Always do it on the top of a HTTPS connection to prevent the man-in-the-middle attack.

java - Best practice for REST token-based authentication with JAX-RS a...

java rest authentication jax-rs jersey-2.0
Rectangle 27 902

What you can do with JAX-RS 2.0 (Jersey, RESTEasy and Apache CXF)

In token-based authentication, the client exchanges hard credentials (such as username and password) for a piece of data called token. For each request, instead of sending the hard credentials, the client will send the token to the server to perform authentication and then authorization.

In a few words, an authentication scheme based on tokens follow these steps:

  • The client sends their credentials (username and password) to the server.
  • The server authenticates the credentials and, if they are valid, generate a token for the user.
  • The server stores the previously generated token in some storage along with the user identifier and an expiration date.
  • The server sends the generated token to the client.
  • The client sends the token to the server in each request.
  • If the token is valid, the server accepts the request.
  • If the token is invalid, the server refuses the request.
  • Once the authentication has been performed, the server performs authorization.
  • The server can provide an endpoint to refresh tokens.

This solution uses only the JAX-RS 2.0 API, avoiding any vendor specific solution. So, it should work with JAX-RS 2.0 implementations, such as Jersey, RESTEasy and Apache CXF.

It is worthwhile to mention that if you are using token-based authentication, you are not relying on the standard Java EE web application security mechanisms offered by the servlet container and configurable via application's web.xml descriptor. It's a custom authentication.

Create a JAX-RS resource method which receives and validates the credentials (username and password) and issue a token for the user:

@Path("/authentication")
public class AuthenticationEndpoint {

    @POST
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    public Response authenticateUser(@FormParam("username") String username, 
                                     @FormParam("password") String password) {

        try {

            // Authenticate the user using the credentials provided
            authenticate(username, password);

            // Issue a token for the user
            String token = issueToken(username);

            // Return the token on the response
            return Response.ok(token).build();

        } catch (Exception e) {
            return Response.status(Response.Status.FORBIDDEN).build();
        }      
    }

    private void authenticate(String username, String password) throws Exception {
        // Authenticate against a database, LDAP, file or whatever
        // Throw an Exception if the credentials are invalid
    }

    private String issueToken(String username) {
        // Issue a token (can be a random String persisted to a database or a JWT token)
        // The issued token must be associated to a user
        // Return the issued token
    }
}

If any exceptions are thrown when validating the credentials, a response with the status 403 (Forbidden) will be returned.

If the credentials are successfully validated, a response with the status 200 (OK) will be returned and the issued token will be sent to the client in the response payload. The client must send the token to the server in every request.

When consuming application/x-www-form-urlencoded, the client must to send the credentials in the following format in the request payload:

username=admin&password=123456

Instead of form params, it's possible to wrap the username and the password into a class:

public class Credentials implements Serializable {

    private String username;
    private String password;

    // Getters and setters omitted
}

And then consume it as JSON:

@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response authenticateUser(Credentials credentials) {

    String username = credentials.getUsername();
    String password = credentials.getPassword();

    // Authenticate the user, issue a token and return a response
}

Using this approach, the client must to send the credentials in the following format in the payload of the request:

{
  "username": "admin",
  "password": "123456"
}

The client should send the token in the standard HTTP Authorization header of the request. For example:

Authorization: Bearer <token-goes-here>

The name of the standard HTTP header is unfortunate because it carries authentication information, not authorization. However, it's the standard HTTP header for sending credentials to the server.

JAX-RS provides @NameBinding, a meta-annotation used to create other annotations to bind filters and interceptors to resource classes and methods. Define a @Secured annotation as following:

@NameBinding
@Retention(RUNTIME)
@Target({TYPE, METHOD})
public @interface Secured { }

The above defined name-binding annotation will be used to decorate a filter class, which implements ContainerRequestFilter, allowing you to intercept the request before it be handled by a resource method. The ContainerRequestContext can be used to access the HTTP request headers and then extract the token:

@Secured
@Provider
@Priority(Priorities.AUTHENTICATION)
public class AuthenticationFilter implements ContainerRequestFilter {

    private static final String AUTHENTICATION_SCHEME = "Bearer";

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {

        // Get the Authorization header from the request
        String authorizationHeader =
                requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);

        // Validate the Authorization header
        if (!isTokenBasedAuthentication(authorizationHeader)) {
            abortWithUnauthorized(requestContext);
            return;
        }

        // Extract the token from the Authorization header
        String token = authorizationHeader
                            .substring(AUTHENTICATION_SCHEME.length()).trim();

        try {

            // Validate the token
            validateToken(token);

        } catch (Exception e) {
            abortWithUnauthorized(requestContext);
        }
    }

    private boolean isTokenBasedAuthentication(String authorizationHeader) {

        // Check if the Authorization header is valid
        // It must not be null and must be prefixed with "Bearer" plus a whitespace
        // Authentication scheme comparison must be case-insensitive
        return authorizationHeader != null && authorizationHeader.toLowerCase()
                    .startsWith(AUTHENTICATION_SCHEME.toLowerCase() + " ");
    }

    private void abortWithUnauthorized(ContainerRequestContext requestContext) {

        // Abort the filter chain with a 401 status code
        // The "WWW-Authenticate" header is sent along with the response
        requestContext.abortWith(
                Response.status(Response.Status.UNAUTHORIZED)
                        .header(HttpHeaders.WWW_AUTHENTICATE, AUTHENTICATION_SCHEME)
                        .build());
    }

    private void validateToken(String token) throws Exception {
        // Check if it was issued by the server and if it's not expired
        // Throw an Exception if the token is invalid
    }
}

If any problems happen during the token validation, a response with the status 401 (Unauthorized) will be returned. Otherwise the request will proceed to a resource method.

To bind the authentication filter to resource methods or resource classes, annotate them with the @Secured annotation created above. For the methods and/or classes that are annotated, the filter will be executed. It means that such endpoints will only be reached if the request is performed with a valid token.

If some methods or classes do not need authentication, simply do not annotate them:

@Path("/example")
public class ExampleResource {

    @GET
    @Path("{id}")
    @Produces(MediaType.APPLICATION_JSON)
    public Response myUnsecuredMethod(@PathParam("id") Long id) {
        // This method is not annotated with @Secured
        // The authentication filter won't be executed before invoking this method
        ...
    }

    @DELETE
    @Secured
    @Path("{id}")
    @Produces(MediaType.APPLICATION_JSON)
    public Response mySecuredMethod(@PathParam("id") Long id) {
        // This method is annotated with @Secured
        // The authentication filter will be executed before invoking this method
        // The HTTP request must be performed with a valid token
        ...
    }
}

In the example shown above, the filter will be executed only for the mySecuredMethod(Long) method because it's annotated with @Secured.

It's very likely that you will need to know the user who is performing the request agains your REST API. The following approaches can be used to achieve it:

Within your ContainerRequestFilter.filter(ContainerRequestContext) method, a new SecurityContext instance can be set for the current request. Then override the SecurityContext.getUserPrincipal(), returning a Principal instance:

final SecurityContext currentSecurityContext = requestContext.getSecurityContext();
requestContext.setSecurityContext(new SecurityContext() {

    @Override
    public Principal getUserPrincipal() {

        return new Principal() {

            @Override
            public String getName() {
                return username;
            }
        };
    }

    @Override
    public boolean isUserInRole(String role) {
        return true;
    }

    @Override
    public boolean isSecure() {
        return currentSecurityContext.isSecure();
    }

    @Override
    public String getAuthenticationScheme() {
        return "Bearer";
    }
});

Use the token to look up the user identifier (username), which will be the Principal's name.

Inject the SecurityContext in any JAX-RS resource class:

@Context
SecurityContext securityContext;

The same can be done in a JAX-RS resource method:

@GET
@Secured
@Path("{id}")
@Produces(MediaType.APPLICATION_JSON)
public Response myMethod(@PathParam("id") Long id, 
                         @Context SecurityContext securityContext) {
    ...
}

And then get the Principal:

Principal principal = securityContext.getUserPrincipal();
String username = principal.getName();

If, for some reason, you don't want to override the SecurityContext, you can use CDI (Context and Dependency Injection), which provides useful features such as events and producers.

Create a CDI qualifier:

@Qualifier
@Retention(RUNTIME)
@Target({ METHOD, FIELD, PARAMETER })
public @interface AuthenticatedUser { }
AuthenticationFilter
Event
@AuthenticatedUser
@Inject
@AuthenticatedUser
Event<String> userAuthenticatedEvent;

If the authentication succeeds, fire the event passing the username as parameter (remember, the token is issued for a user and the token will be used to look up the user identifier):

userAuthenticatedEvent.fire(username);

It's very likely that there's a class that represents a user in your application. Let's call this class User.

Create a CDI bean to handle the authentication event, find a User instance with the correspondent username and assign it to the authenticatedUser producer field:

@RequestScoped
public class AuthenticatedUserProducer {

    @Produces
    @RequestScoped
    @AuthenticatedUser
    private User authenticatedUser;

    public void handleAuthenticationEvent(@Observes @AuthenticatedUser String username) {
        this.authenticatedUser = findUser(username);
    }

    private User findUser(String username) {
        // Hit the the database or a service to find a user by its username and return it
        // Return the User instance
    }
}

The authenticatedUser field produces a User instance that can be injected into container managed beans, such as JAX-RS services, CDI beans, servlets and EJBs. Use the following piece of code to inject a User instance (in fact, it's a CDI proxy):

@Inject
@AuthenticatedUser
User authenticatedUser;

Note that the CDI @Produces annotation is different from the JAX-RS @Produces annotation:

javax.enterprise.inject.Produces
javax.ws.rs.Produces

Be sure you use the CDI @Produces annotation in your AuthenticatedUserProducer bean.

The key here is the bean annotated with @RequestScoped, allowing you to share data between filters and your beans. If you don't wan't to use events, you can modify the filter to store the authenticated user in a request scoped bean and then read it from your JAX-RS resource classes.

Compared to the approach that overrides the SecurityContext, the CDI approach allows you to get the authenticated user from beans other than JAX-RS resources and providers.

A token can be:

  • Opaque: Reveals no details other than the value itself (like a random string)
  • Self-contained: Contains details about the token itself (like JWT).

A token can be issued by generating a random string and persisting it to a database along with the user identifier and an expiration date. A good example of how to generate a random string in Java can be seen here. You also could use:

Random random = new SecureRandom();
String token = new BigInteger(130, random).toString(32);

JWT (JSON Web Token) is a standard method for representing claims securely between two parties and is defined by the RFC 7519.

It's a self-contained token and it enables you to store details in claims. These claims are stored in the token payload which is a JSON encoded as Base64. Here are some claims registered in the RFC 7519 and what they mean (read the full RFC for further details):

  • iss: Principal that issued the token.
  • sub: Principal that is the subject of the JWT.
exp
nbf
  • iat: Time on which the token was issued.
jti

Be aware that you must not store sensitive data, such as passwords, in the token.

The payload can be read by the client and the integrity of the token can be easily checked by verifying its signature on the server. The signature is what prevents the token from being tampered with.

You won't need to persist JWT tokens if you don't need to track them. Althought, by persisting the tokens, you will have the possibility of invalidating and revoking the access of them. To keep the track of JWT tokens, instead of persisting the whole token on the server, you could persist the token identifier (jti claim) along with some other details such as the user you issued the token for, the expiration date, etc.

When persisting tokens, always consider removing the old ones in order to prevent your database from growing indefinitely.

There are a few Java libraries to issue and validate JWT tokens such as:

To find some other great resources to work with JWT, have a look at http://jwt.io.

Accept only valid (and non-expired) tokens for refreshment. It's responsability of the client to refresh the tokens before the expiration date indicated in the exp claim.

You should prevent the tokens from being refreshed indefinitely. See below a few approaches that you could consider.

You could keep the track of token refreshment by adding two claims to your token (the claim names are up to you):

  • refreshLimit: Indicates how many times the token can be refreshed.
  • refreshCount: Indicates how many times the token has been refreshed.

So only refresh the token if the following conditions are true:

  • The token is not expired (exp >= now).
  • The number of times that the token has been refreshed is less than the number of times that the token can be refreshed (refreshCount < refreshLimit).

And when refreshing the token:

exp = now + some-amount-of-time
  • Increment the number of times that the token has been refreshed (refreshCount++).

Alternatively to keeping the track of the number of refreshments, you could have a claim that indicates the absolute expiration date (which works pretty similar to the refreshLimit claim described above). Before the absolute expiration date, any number of refreshments is acceptable.

Another approach involves issuing a separate long-lived refresh token that is used to issue short-lived JWT tokens.

If you want to revoke tokens, you must keep the track of them. You don't need to store the whole token on server side, store only the token identifier (that must be unique) and some metadata if you need. For the token identifier you could use UUID.

The jti claim should be used to store the token identifier on the token. When validating the token, ensure that it has not been revoked by checking the value of the jti claim against the token identifiers you have on server side.

For security purposes, revoke all the tokens for a user when they change their password.

  • It doesn't matter which type of authentication you decide to use. Always do it on the top of a HTTPS connection to prevent the man-in-the-middle attack.

java - Best practice for REST token-based authentication with JAX-RS a...

java rest authentication jax-rs jersey-2.0
Rectangle 27 4

is the username and password set on the client like:

cc.ClientCredentials.UserName.UserName = ReturnUsername();
cc.ClientCredentials.UserName.Password = ReturnPassword();

Or are they embedded in the body of the REST message?

If the latter, you can set the service to no security, and use a custom ServiceAuthorizationManager to validate the contents of the message: http://msdn.microsoft.com/en-us/library/ms731774.aspx

Hope one or the other helps! I'd try to post sample code & config, but I'm @ home and dont have access to code, which is all @ work.

Basic Authentication with WCF REST service to something other than win...

wcf rest
Rectangle 27 5

One good method is to have a login method, taking the username and password (hopefully over TLS). You give them an expiring token if they successfully auth; the rest of their API calls must contain this token to succeed.

@Hasan Khan Note that the token doesn't need to be stored in shared state; it could simply be deterministically created using a server-side secret (e.g. date hashed with secret, hour hashed with secret, or timestamp reversibly encrypted). So you can use a stateful store which will probably scale to at least thousands of requests a second without issue and choose a more performant option if and when needed.

rest - RESTful API Authentication - Stack Overflow

api rest restful-authentication
Rectangle 27 2

Step wise solution for your problem can be..

  • Use spring security UsernamePasswordAuthenticationFilter to authenticate the user through Username and password and generate a unique token.
  • Write another custom security filter and AuthenticationProvider implementation to authenticate the user for successive request.
UsernamePasswordAuthenticationFilter
AuthenticationProvider
AuthenticationManager

Note:- A better way to secure your rest APIs is to use some standard protocols like oauth1a, oauth2.0 etc. Spring provides a novel implementation of oauth1a and oauth2.0 protocol.

java - Spring Security with REST API - Stack Overflow

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

If the REST application and the Java web application are the same Webapp, then you only need to check subject.isAuthenticated(). Use a session cookie without the password or username (it isn't a good idea to be passing around the password as it could be stolen).

Most of this behavior comes by default if both parts are in the same Webapp.

In your REST method you'd have something like:

Subject subject = SecurityUtils.getSubject();
if(subject == null || !subject.isAuthenticated()) {
     return 401; // Not Authorized
}

Thank you @Stephen. Yes, the Java web application and the REST one share the same webapp. The authentication code on server processes on that session cookie. But my REST application is a mobile app, so I am not sure that I can use session cookie on it. I prefer using a token (generated from username and password) and attach it on every single request. As a result, I need to re-implement the authentication step and cannot re-use the old one. Anyway, your hint may help me a lot, and I will give it a try on that way.

java - Sample about RESTful and Shiro Integration - Stack Overflow

java rest shiro
Rectangle 27 7

You could take a look into Shiro: http://shiro.apache.org It is a very nice framework to "secure" APIs (authorization, authentication and other things for security). You can implement a "basic authentication" to "login" your users (via a username/password), then provide them with an API key, which you can use to perform a "bearer token authentication" to allow them to access the resources of your API. To do that you would define what shiro calls "filters", which are defined over API resources... this is defined in a "shiro.ini" as the following:

[main]
authcBasicRealm = com.yourapp.shiro.UserAuthenticatorRealm
tokenValidatorFilter = com.yourapp.shiro.BearerAuthenticationTokenFilter
tokenValidatorRealm = com.yourapp.shiro.BearerAuthenticationTokenRealm

[urls]
/rest/hello/login/** = ssl[8443], noSessionCreation, authcBasic
/rest/hello/hello = ssl[8443], noSessionCreation, tokenValidatorFilter

You need to implement/extend some of the Shiro default filters to make them work with your DB to get your user authentication data, etc. The nice thing is that they provide many tools to handle security issues, e.g.: to generate API keys, to salt and encrypt, etc. Take a look on their tutorials, they are in general very good.

There are other frameworks, namely Java EE has support for security and also Spring provides support for security. Take a look at this very nice presentation by Mat Raible where he presents and demos these three frameworks: http://www.slideshare.net/mraible/java-web-application-security-denver-jug-2013

I understand... but if you want to manage all those different aspects of security in your web service (basic authorization over HTTPS, then generate and give key to users, then authenticate the key, etc.) you will probably be doing the type of operations I presented yourself... which I avoid to do myself, since I am no security expert, and prefer to rely on a framework designed to cope with those things. Java EE, Spring also have frameworks/libraries to deal with security if you are using one of those (I updated my answer with reference to those).

REST API key generation strategy - Stack Overflow

api rest authentication jax-rs
Rectangle 27 8

package com.example.jirasandbox;

import com.atlassian.jira.rest.client.api.JiraRestClient;
import com.atlassian.jira.rest.client.api.JiraRestClientFactory;
import com.atlassian.jira.rest.client.api.domain.BasicProject;
import com.atlassian.jira.rest.client.api.domain.Issue;
import com.atlassian.jira.rest.client.api.domain.SearchResult;
import com.atlassian.jira.rest.client.api.domain.User;
import com.atlassian.jira.rest.client.internal.async.AsynchronousJiraRestClientFactory;
import com.atlassian.util.concurrent.Promise;
import java.net.URI;

public class CustomJiraRestClient {

    private static final String JIRA_URL = "http://jira-dev:8080";
    private static final String JIRA_ADMIN_USERNAME = "admin";
    private static final String JIRA_ADMIN_PASSWORD = "admin";

    public static void main(String[] args) throws Exception {
        // Construct the JRJC client
        System.out.println(String.format("Logging in to %s with username '%s' and password '%s'", JIRA_URL, JIRA_ADMIN_USERNAME, JIRA_ADMIN_PASSWORD));
        JiraRestClientFactory factory = new AsynchronousJiraRestClientFactory();
        URI uri = new URI(JIRA_URL);
        JiraRestClient client = factory.createWithBasicHttpAuthentication(uri, JIRA_ADMIN_USERNAME, JIRA_ADMIN_PASSWORD);

        // Invoke the JRJC Client
        Promise<User> promise = client.getUserClient().getUser("admin");
        User user = promise.claim();

        for (BasicProject project : client.getProjectClient().getAllProjects().claim()) {
            System.out.println(project.getKey() + ": " + project.getName());
        }

        Promise<SearchResult> searchJqlPromise = client.getSearchClient().searchJql("project = MYPURRJECT AND status in (Closed, Completed, Resolved) ORDER BY assignee, resolutiondate");

        for (Issue issue : searchJqlPromise.claim().getIssues()) {
            System.out.println(issue.getSummary());
        }

        // Print the result
        System.out.println(String.format("Your admin user's email address is: %s\r\n", user.getEmailAddress()));

        // Done
        System.out.println("Example complete. Now exiting.");
        System.exit(0);
    }
}

Thanks a lot, in that working example the String URL is my jira, right? And Promise<SearchResult> searchJqlPromise = client.getSearchClient().searchJql("project = MYPURRJECT AND status in (Closed, Completed, Resolved) ORDER BY assignee, resolutiondate"); - how should you know how to specify that?

Your connection to jira is in this.restClientobject . Use restClient.getSearchClient().searchJql(JQLquery) function with JQL query to get issues you want. To get JQL query log into Jira and in issue navigator search for issues you want, then switch to Advanced search using JQL and there is your JQL query.

Yes, the JIRA_URL points to your jira. Also, @ThePavolC gets it right, you can issue JQL queries on the site there. "Issues" menu on the top, then "Search for Issues" menuitem, then click the "Advanced" link.

You mean to include the stuff that resides now in pastebin?

How to get all issues of project via Jira REST Java Client? - Stack Ov...

jira jira-rest-api jira-rest-java-api
Rectangle 27 2

As you are talking about PHP and javascript I assume that you are talking about a HTTP (REST) api. In that case I would almost always argue to use the standard HTTP Authentication. This sends a username and password encoded in BASE64. This might look encrypted but is, as the name says, just an encoding. Therefore it is not secure. If you want that securely, I strongly suggest to use HTTPS.

EDIT: As requested a short summary of how this works. The long (and somewhat hard to read) standard describes, the server can request the client to authenticate itself. The client then sends username and password (the base 64encoded version of username:password) to the server. As this Basic HTTP Authentication is specified in the standard it is quite widely spread and there are tons of libraries in pretty much every language for it. However, as mentioned previously I would strongly suggest to use it with HTTPS. Otherwise it does nothing but exposing the password of the user to the internet.

Although I'm strongly in favor of using the standard HTTP authentication, you might also want to have look at other concepts: OAuth, apikeys, Amazon Stuff

Maybe you could summarize the method here, a bit?

php - Authenticating access to an API - Stack Overflow

php javascript api
Rectangle 27 1

If you want more control over the security of REST Web services then you can think about implementing your own authentication and RBAC(Role based access control). Simply take username and password with every request in header over HTTPS and implement the RBAC on your REST Webservice layer. You can basically add Servlet filters to do the authentication and authorization before the request is actually handed over to the Web service.

Choice is yours, there are obviously different security frameworks available but you have to chose what meets the best for your requirement.

Security of web services (REST & SOAP) - Stack Overflow

web-services security rest soap spring-security
Rectangle 27 1

If you want more control over the security of REST Web services then you can think about implementing your own authentication and RBAC(Role based access control). Simply take username and password with every request in header over HTTPS and implement the RBAC on your REST Webservice layer. You can basically add Servlet filters to do the authentication and authorization before the request is actually handed over to the Web service.

Choice is yours, there are obviously different security frameworks available but you have to chose what meets the best for your requirement.

Security of web services (REST & SOAP) - Stack Overflow

web-services security rest soap spring-security
Rectangle 27 1

We implement wsse authentication to our symfony REST endpoints. But we dont use the password field. We added a new field called token to the user entity. The REST api is consumed by mobile app. When users login to the app using either facebook OR their username and password, the credentials/fb access token are sent to symfony app over https, the server responds with the user profile and a fresh token ( token is regenerated on every login ). We are using this bundle tough. https://github.com/escapestudios/EscapeWSSEAuthenticationBundle

So when you are validating the digest, you would build the expected digest using the user's token.

So, this is similar to the step 1 you suggested, just that you don,t give away password and salt. You'll have the flexibility to change the user's token without changing the password.

In any case, the client will need to enter their username and password in order to actually authenticate first and retrieve the token. Even if you implement oAuth, the user will need to first authenticate to your service provider in order to authorize your app.

php - Symfony2 RESTfull API Wsse authentication with Bcrypt - Stack Ov...

php symfony authentication hash bcrypt
Rectangle 27 1

Instead of encoding the username and password in url, they should be in the request body. The reason is that even though https encrypt the url, it is not a good practice because if the url is called from browser, the browser will remember it and username/password will be visible there in the browser history. Thus, here is an article to handle http Post http://www.codeproject.com/Tips/150313/Simple-WCF-web-service-to-receive-parameter-from-H

Need advice on authentication for android client connecting to the WCF...

android wcf design authorization restful-authentication
Rectangle 27 1

Instead of encoding the username and password in url, they should be in the request body. The reason is that even though https encrypt the url, it is not a good practice because if the url is called from browser, the browser will remember it and username/password will be visible there in the browser history. Thus, here is an article to handle http Post http://www.codeproject.com/Tips/150313/Simple-WCF-web-service-to-receive-parameter-from-H

Need advice on authentication for android client connecting to the WCF...

android wcf design authorization restful-authentication
Rectangle 27 0

If you're having a REST API as the back end, then you must have implemented oAuth as an authentication mechanism. That is, when your user logs in, using a username and a password, you exchange that data with an authentication token. This authentication token is sent your server with each and every API call and your backend validates this token before servicing the request. Clear so far?

What you could do is, when you obtain the access token, you can also obtain the access token expiration time from the server and store that data in your client side app. In localStorage maybe? And when your user closes the browser and reopens again, you can first check whether such access token is available (and not expired) before asking the user to log in. This should solve your first problem.

Secondly, if you're looking for a lightweight routing option, I recommend director.

I think I am doing something along the lines of what you are saying. Although in my case.. at least with my jquery use right now, on document load I do a GET check to an API to see if the user is logged in. Perhaps a better choice is to read the document.cookie and look for my server specific cookie, rather than an ajax request on load? The idea behind ajax request on load was that the request, if a cookie is present, would allow the ajax handler to use the cookie and verify if the user/session is valid, not timed out, etc.

Well, since you're validating your user's auth token on every request, why would you want to check if the user is logged on explicitly?

I've actually changed how I do this. I have the luxury to not need to support IE9 or earlier, so decided that I am going to use local storage for storing a session token, and if the page is reloaded, I check for the session token upon page load and if found, redirect the user to their logged in dashboard. If the user selects logout I'll remove the session token. If for example they come back hours later, during the check if it's expired, it will be removed and they'll be at the main page again, where they can then log in again.

That is the best approach to do it. I have done it the same way. I also maintain the expiration time on the localstorage as well. That way, if it's expired, I don't need a call to the server to redirect the user to the login page.

That's a good point... I'll add that in. From what I understand, localStorage is safe in that it can only be accessed by javascript from the same server. Is there any chance though that client side could modify the localStorage timestamp value? It shouldn't matter as every request should validate the session token + time stamp anyway.

javascript - How to manage server user session within client side sing...

javascript jquery jsp session single-page-application
Rectangle 27 0

I found a solution that works for me. I realised that I don't need another @Configuration because the default jhipster configuration does not redirect to login page for unauthenticated access - it returns a 401 which is I want for the REST api too. So I just registered a user with the username and password that I want to use for the REST api and added the following line to the bottom of the configure method in

`.antMatchers("/basicAuthApi/**").hasAuthority(AuthoritiesConstants.USER).and().httpBasic();`

I will now try to improve this by creating an API role and giving that role to users who need to call the REST API

java - In addition to token based authentication, allow Rest api endpo...

java spring-security spring-boot jhipster
Rectangle 27 0

you cache the information that rarely changes. Like Country, States etc. and it is not preferred to cache the transactional data.

There are no specific answer to your question but I would not prefer to cache the user login information as I consider it as transactional data.

Read more information about hibernate cache here or read the API.

Sure you are right, but how would one prevent a username password lookup per rest api call? Due to the stateless nature I cant think of another way to optimise this @ManuPK

hibernate - good idea to use cache for username and password rest api ...

hibernate api rest ehcache
Rectangle 27 0

The http basic auth stores the username and password on the client side, and it sends it again with every request. So by REST you have to send these identification factors and authenticate by every request...

You can cache the authentication mechanism if you want it to be faster...

This is an important thing by REST... REST stores the session on client side, not on server side... If you want store something important on server side, then it has to be a resource or a property of a resource...

If you allow somebody to write 3rd party application (another client for your REST service), then the user should accept that this 3rd party application can send requests in his/her name. Ofc. the user does not want to share his/her password, so give permissions to 3rd party applications is a hard stuff. For example oauth solves this problem...

The basic concept by 3rd party applications (clients), that you ask the user whether it allows them to send certain requests or not. For example by facebook it asks, if you want share your identity, list of acquaintances, etc... and you allow to send posts in your behalf, etc... After you clicked ok, the REST application should store that information and give the client permissions to your account. How to check who sends the requests? Ofc. CSRF is not allowed, so the 3rd party client cannot send a cross domain request on your behalf with the client you are using. So it has to send its requests trough a different connection, probably with curl. What should it send? Ofc. the request details. What else? Its identity (an api key) and your identity. This is the most basic approach.

There are other solutions. You can use a similar approach to what you are using by storing passwords in a database. You store only hashes of the passwords hashed with a slow algorithm. By the authentication you create the hash again on the given password. When the stored hash is equal with the newly created, then the application accepts the identity and grants access to the account. You can use the same approach by requests. The 3rd party client requires a hash for a request. After that it sends the request with the hash it got, and by getting the request, the server compares that hash with the hash it creates based on the content of the request. If they are equal, the request is valid. This is cool stuff, because it prevents a CSRF attack on a 3rd party client as well...

I guess there are many other, more complex approaches, I don't know, I am not a security expert and probably you won't be either. You just have to understand the basics and use a tool for example oauth if you want to allow 3rd party access to your api. If you don't want that, then probably you don't need a REST application, just a simple web application... That depends on your needs, visitor count, etc...

web services - Online application with RESTful webservice design - Sta...

web-services rest restful-authentication
Rectangle 27 0

Taking a look at gist provided, the credentials are being set inside the login method. So the LoginView is supplied a new Credentials model. Inside the Login method, the username and password are being set to the Credentials Model. Now when you call this.model.save() after credentials have been set, the model will be sent to the server. On the server you are able to then retrieve the username and password from your Credentials Model. I think there is a better way to authenticate a user though. A basic look at REST Authentication.

javascript - few questions on backbone.js - Stack Overflow

javascript backbone.js