I'm just starting to learn oAuth2 authorization to secure my API. and the process is quite complicated. my API is developed using Jersey, and Apache Oltu as the oAuth2 Authorization. now, the token can be generated, but, every time i try to generate a new token, the server create a new instance of @ApplicationScoped bean. this is the bean code i got from internet :
@ApplicationScoped
public class Database {
private Set<String> authCodes = new HashSet<>();
private Set<String> tokens = new HashSet<>();
public void addAuthCode(String authCode) {
authCodes.add(authCode);
}
public boolean isValidAuthCode(String authCode) {
return authCodes.contains(authCode);
}
public void addToken(String token) {
tokens.add(token);
}
public boolean isValidToken(String token) {
return tokens.contains(token);
}
}
and this is the Authorization code :
@Path("/authz")
public class AuthzEndpoint {
@Inject
Database database;
@GET
public Response authorize(@Context HttpServletRequest request)
throws URISyntaxException, OAuthSystemException {
try {
OAuthAuthzRequest oauthRequest = new OAuthAuthzRequest(request);
OAuthIssuerImpl oauthIssuerImpl = new OAuthIssuerImpl(new MD5Generator());
//build response according to response_type
String responseType = oauthRequest.getParam(OAuth.OAUTH_RESPONSE_TYPE);
OAuthASResponse.OAuthAuthorizationResponseBuilder builder =
OAuthASResponse.authorizationResponse(request, HttpServletResponse.SC_FOUND);
if (responseType.equals(ResponseType.CODE.toString())) {
final String authorizationCode = oauthIssuerImpl.authorizationCode();
database.addAuthCode(authorizationCode);
builder.setCode(authorizationCode);
}
if (responseType.equals(ResponseType.TOKEN.toString())) {
final String accessToken = oauthIssuerImpl.accessToken();
database.addToken(accessToken);
builder.setAccessToken(accessToken);
builder.setExpiresIn(3600l);
}
String redirectURI = oauthRequest.getParam(OAuth.OAUTH_REDIRECT_URI);
final OAuthResponse response = builder.location(redirectURI).buildQueryMessage();
URI url = new URI(response.getLocationUri());
return Response.status(response.getResponseStatus()).location(url).build();
} catch (OAuthProblemException e) {
final Response.ResponseBuilder responseBuilder = Response.status(HttpServletResponse.SC_FOUND);
String redirectUri = e.getRedirectUri();
if (OAuthUtils.isEmpty(redirectUri)) {
throw new WebApplicationException(
responseBuilder.entity("OAuth callback url needs to be provided by client!!!").build());
}
final OAuthResponse response =
OAuthASResponse.errorResponse(HttpServletResponse.SC_FOUND)
.error(e).location(redirectUri).buildQueryMessage();
final URI location = new URI(response.getLocationUri());
return responseBuilder.location(location).build();
}
}
}
as you can see, there are @Inject annotation of database there, and called addToken() method in some part of the code. and when i try to validate the token from my main web services, the Database bean is empty. this is the code
@Inject
Database database;
@POST
@Path("validateLogin")
@Consumes("application/x-www-form-urlencoded")
@Produces({"application/xml", "application/json", "text/plain", "text/html"})
public Response validateLogin(@HeaderParam("Authorization") String token, @FormParam("username") String username, @FormParam("password") String password) {
System.out.println(token.substring(7,token.length()));
System.out.println(database.isValidToken(token.substring(7, token.length())));
System.out.println(database);
if (!database.isValidToken(token.substring(7, token.length()))) {
return Response.status(Response.Status.UNAUTHORIZED).build();
}
else {
String result;
if (username == null || password == null) {
return Response.status(Response.Status.BAD_REQUEST).build();
}
else {
STCWebService stcWebService = new STCWebService();
result = stcWebService.validateLogin(username,password);
if (result.isEmpty()) {
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
}
else {
return Response
.status(200)
.entity(result)
.type(MediaType.APPLICATION_JSON)
.header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT")
.build();
}
}
}
}
i have been thinking there might be some mistake in web.xml file or ResourceConfig.java or even in ApplicationBinder. i have stumbled this problem for hours. any help is appreciated.
EDIT
this is the ApplicationBinder Code
public class MyApplicationBinder extends AbstractBinder {
@Override
protected void configure() {
bind(Database.class).to(Database.class);
}
}
and is linked to this MyApplication
public class MyApplication extends ResourceConfig {
public MyApplication() {
register(new MyApplicationBinder());
packages("com.package");
}
}
i created the ApplicationBinder and MyApplication code based on this question Dependency injection with Jersey 2.0