Skip to content

Commit

Permalink
Making authN filters
Browse files Browse the repository at this point in the history
  • Loading branch information
ajs6f committed Jun 3, 2013
1 parent 085c1d6 commit 6c93394
Show file tree
Hide file tree
Showing 6 changed files with 221 additions and 25 deletions.
11 changes: 2 additions & 9 deletions pom.xml
Expand Up @@ -7,7 +7,7 @@
<version>4.0-SNAPSHOT</version>
</parent>
<artifactId>fcrepo-auth-oauth</artifactId>
<name>Apache Oltu OAuth2 module for Fedora Commons</name>
<name>Apache Oltu OAuth2 module for Fedora Commons 4</name>
<dependencies>
<dependency>
<artifactId>fcrepo-http-api</artifactId>
Expand Down Expand Up @@ -85,14 +85,7 @@
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<!-- This dependency is for compile-time: it keeps this module independent
of any given choice of JAX-RS implementation. It must be _after_ the test
gear. Otherwise it will get loaded during test phase, but because this is
just an API, the tests will not be able to execute. -->
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
</dependency>

</dependencies>
<repositories>
<repository>
Expand Down
15 changes: 12 additions & 3 deletions src/main/java/org/fcrepo/auth/oauth/api/TokenEndpoint.java
Expand Up @@ -8,6 +8,7 @@
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import static javax.ws.rs.core.Response.status;

import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.servlet.http.HttpServletRequest;
Expand Down Expand Up @@ -35,6 +36,8 @@
import org.apache.oltu.oauth2.common.message.OAuthResponse;
import org.apache.oltu.oauth2.common.message.types.GrantType;
import org.fcrepo.AbstractResource;
import static org.fcrepo.auth.oauth.filter.Constants.CLIENT_PROPERTY;
import static org.fcrepo.auth.oauth.filter.Constants.PRINCIPAL_PROPERTY;
import org.springframework.stereotype.Component;

@Component
Expand Down Expand Up @@ -117,8 +120,10 @@ public Response authorize(@Context
return status(response.getResponseStatus()).entity(
response.getBody()).build();
}

final String token = oauthIssuerImpl.accessToken();
saveToken(token);
saveToken(token, oauthRequest.getClientId(), oauthRequest
.getUsername());
final OAuthResponse response =
tokenResponse(SC_OK).setAccessToken(token).setExpiresIn(
"3600").buildJSONMessage();
Expand All @@ -133,10 +138,14 @@ public Response authorize(@Context
}
}

private void saveToken(final String token) throws RepositoryException {
private void saveToken(final String token, final String client,
final String username) throws RepositoryException {
final Session session = sessions.getSession();
try {
jcrTools.findOrCreateNode(session, "/tokens/" + token);
final Node tokenNode =
jcrTools.findOrCreateNode(session, "/tokens/" + token);
tokenNode.setProperty(CLIENT_PROPERTY, client);
tokenNode.setProperty(PRINCIPAL_PROPERTY, username);
session.save();
} finally {
session.logout();
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/org/fcrepo/auth/oauth/filter/Constants.java
@@ -0,0 +1,9 @@

package org.fcrepo.auth.oauth.filter;

public interface Constants {

public static final String CLIENT_PROPERTY = "oauth:client";

public static final String PRINCIPAL_PROPERTY = "oauth:principal";
}
23 changes: 15 additions & 8 deletions src/main/java/org/fcrepo/auth/oauth/filter/Decision.java
Expand Up @@ -12,11 +12,17 @@ public class Decision implements OAuthDecision {

private Principal principal;

private boolean authorized;
private boolean isAuthorized;

public Decision(final String client, final String principal,
final Boolean isAuthorized) {
this.oAuthClient = null;
public Decision(final String client, final String principal) {
this.oAuthClient = new OAuthClient() {

@Override
public String getClientId() {
return client;
}

};
this.principal = new Principal() {

@Override
Expand All @@ -25,7 +31,6 @@ public String getName() {
}

};
this.authorized = isAuthorized;
}

@Override
Expand All @@ -35,14 +40,16 @@ public OAuthClient getOAuthClient() {

@Override
public Principal getPrincipal() {
// TODO Auto-generated method stub
return principal;
}

@Override
public boolean isAuthorized() {
// TODO Auto-generated method stub
return authorized;
return isAuthorized;
}

public void setAuthorized(final boolean isAuthorized) {
this.isAuthorized = isAuthorized;
}

}
Expand Up @@ -2,6 +2,7 @@
package org.fcrepo.auth.oauth.filter;

import static com.google.common.base.Throwables.propagate;
import static org.slf4j.LoggerFactory.getLogger;

import javax.jcr.Node;
import javax.jcr.RepositoryException;
Expand All @@ -13,15 +14,19 @@
import org.apache.oltu.oauth2.rsfilter.OAuthDecision;
import org.apache.oltu.oauth2.rsfilter.OAuthRSProvider;
import org.fcrepo.session.SessionFactory;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class DefaultOAuthResourceProvider implements OAuthRSProvider {
public class DefaultOAuthResourceProvider implements OAuthRSProvider, Constants {

@Autowired
SessionFactory sessionFactory;

private static final Logger LOGGER =
getLogger(DefaultOAuthResourceProvider.class);

@Override
public OAuthDecision validateRequest(final String rsId, final String token,
final HttpServletRequest req) throws OAuthProblemException {
Expand All @@ -33,13 +38,16 @@ public OAuthDecision validateRequest(final String rsId, final String token,
throw new OAuthRuntimeException("Invalid token!");
} else {
final Node tokenNode = session.getNode("/tokens/" + token);
LOGGER.debug("Retrieved token from: {}", tokenNode
.getPath());
final String client =
tokenNode.getProperty("oauth:client").getString();
tokenNode.getProperty(CLIENT_PROPERTY).getString();
LOGGER.debug("Retrieved client: {}", client);
final String principal =
tokenNode.getProperty("oauth:principal")
tokenNode.getProperty(PRINCIPAL_PROPERTY)
.getString();

return new Decision(client, principal, authorized);
LOGGER.debug("Retrieved principal: {}", principal);
return new Decision(client, principal);
}
} finally {
session.logout();
Expand Down
170 changes: 170 additions & 0 deletions src/main/java/org/fcrepo/auth/oauth/filter/InjectableOAuthFilter.java
@@ -0,0 +1,170 @@

package org.fcrepo.auth.oauth.filter;

import java.io.IOException;
import java.security.Principal;
import java.util.Set;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;

import org.apache.oltu.oauth2.common.OAuth;
import org.apache.oltu.oauth2.common.error.OAuthError;
import org.apache.oltu.oauth2.common.exception.OAuthProblemException;
import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
import org.apache.oltu.oauth2.common.message.OAuthResponse;
import org.apache.oltu.oauth2.common.message.types.ParameterStyle;
import org.apache.oltu.oauth2.rs.request.OAuthAccessResourceRequest;
import org.apache.oltu.oauth2.rs.response.OAuthRSResponse;
import org.apache.oltu.oauth2.rsfilter.OAuthDecision;
import org.apache.oltu.oauth2.rsfilter.OAuthFilter;
import org.apache.oltu.oauth2.rsfilter.OAuthRSProvider;
import org.apache.oltu.oauth2.rsfilter.OAuthUtils;

public class InjectableOAuthFilter implements Filter {

public static final String OAUTH_RS_PROVIDER_CLASS =
"oauth.rs.provider-class";

public static final String RS_REALM = "oauth.rs.realm";

public static final String RS_TOKENS = "oauth.rs.tokens";

private String realm;

private OAuthRSProvider provider;

private Set<String> parameterStylesSet;

private ParameterStyle[] parameterStyles;

@Override
public void init(final FilterConfig filterConfig) throws ServletException {

final String parameterStylesString =
filterConfig.getServletContext().getInitParameter(RS_TOKENS);

int i = 0;
for (final String parameterStyleName : parameterStylesSet) {
final ParameterStyle tempParameterStyle =
ParameterStyle.valueOf(parameterStyleName);
if (tempParameterStyle != null) {
parameterStyles[i++] = tempParameterStyle;
} else {
throw new ServletException("Incorrect ParameterStyle: " +
parameterStyleName);
}
}
}

@Override
public void doFilter(ServletRequest request,
final ServletResponse response, final FilterChain chain)
throws IOException, ServletException {
final HttpServletRequest req = (HttpServletRequest) request;
final HttpServletResponse res = (HttpServletResponse) response;

try {

// Make an OAuth Request out of this servlet request
final OAuthAccessResourceRequest oauthRequest =
new OAuthAccessResourceRequest(req, parameterStyles);

// Get the access token
final String accessToken = oauthRequest.getAccessToken();

final OAuthDecision decision =
provider.validateRequest(realm, accessToken, req);

final Principal principal = decision.getPrincipal();

request =
new HttpServletRequestWrapper((HttpServletRequest) request) {

@Override
public String getRemoteUser() {
return principal != null ? principal.getName()
: null;
}

@Override
public Principal getUserPrincipal() {
return principal;
}

};

request.setAttribute(OAuth.OAUTH_CLIENT_ID, decision
.getOAuthClient().getClientId());

chain.doFilter(request, response);
return;

} catch (final OAuthSystemException e1) {
throw new ServletException(e1);
} catch (final OAuthProblemException e) {
respondWithError(res, e);
return;
}

}

@Override
public void destroy() {

}

private void respondWithError(final HttpServletResponse resp,
final OAuthProblemException error) throws IOException,
ServletException {

OAuthResponse oauthResponse = null;

try {
if (OAuthUtils.isEmpty(error.getError())) {
oauthResponse =
OAuthRSResponse.errorResponse(
HttpServletResponse.SC_UNAUTHORIZED).setRealm(
realm).buildHeaderMessage();

} else {

int responseCode = 401;
if (error.getError().equals(
OAuthError.CodeResponse.INVALID_REQUEST)) {
responseCode = 400;
} else if (error.getError().equals(
OAuthError.ResourceResponse.INSUFFICIENT_SCOPE)) {
responseCode = 403;
}

oauthResponse =
OAuthRSResponse.errorResponse(responseCode).setRealm(
realm).setError(error.getError())
.setErrorDescription(error.getDescription())
.setErrorUri(error.getUri())
.buildHeaderMessage();
}
resp.addHeader(OAuth.HeaderType.WWW_AUTHENTICATE, oauthResponse
.getHeader(OAuth.HeaderType.WWW_AUTHENTICATE));
resp.sendError(oauthResponse.getResponseStatus());
} catch (final OAuthSystemException e) {
throw new ServletException(e);
}
}

public void setRealm(final String realm) {
this.realm = realm;
}

public void setProvider(final OAuthRSProvider provider) {
this.provider = provider;
}

public void setParameterStyles(final Set<String> parameterStylesSet) {
this.parameterStylesSet = parameterStylesSet;
}

}

0 comments on commit 6c93394

Please sign in to comment.