-
1. Re: wildfly http header based identity assertion
sony2006 Jan 12, 2016 12:46 AM (in response to sony2006)I finally got this done as below. Not sure whether this the the correct approach or a better one is available.
1. ServletExtention where custom SSOHandler and custom identityAssertion authentication mechanism are registered.
public class IdentityAssertionHandlerExtension implements ServletExtension{
@Override
public void handleDeployment(DeploymentInfo deploymentInfo,ServletContext servletContext) {
// Case where header token bases SSO need to be implemented
deploymentInfo.addInnerHandlerChainWrapper(new HandlerWrapper() {
@Override
public HttpHandler wrap(HttpHandler handler) {
return Handlers.predicate(new HeaderTokenPredicate(IdentityAsserterLoginModule.SSO_TOKEN_TYPE), new SSOHandler(handler), handler);
}
});
// For SOAP services which relies on header for authentication
deploymentInfo.addAuthenticationMechanism("IDTY-ASSERT",
new IdentityAssertionAuthenticationMechanismFactory(deploymentInfo.getIdentityManager()));
}
}
2. IdentityAssertionAuthenticationMechanism for normal HTTP requests which will be come after authentication in external system like access manager
public class IdentityAssertionAuthenticationMechanismFactory implements AuthenticationMechanismFactory{
private final IdentityManager identityManager;
public IdentityAssertionAuthenticationMechanismFactory(IdentityManager identityManager) {
this.identityManager = identityManager;
}
@Override
public AuthenticationMechanism create(String mechanismName, FormParserFactory formParserFactory,
Map<String, String> properties) {
// TODO Auto-generated method stub
return new IdentityAssertionAuthenticationMechanism(mechanismName,identityManager,properties);
}
}
public class IdentityAssertionAuthenticationMechanism implements AuthenticationMechanism {
public final static String TOKEN_PREFIX = "icSessionId:";
protected TrivialLog log = TrivialLog.getInstance();
private String name;
private IdentityManager identityManager;
Map<String, String> properties = new HashMap<String,String>();
public IdentityAssertionAuthenticationMechanism(String name, IdentityManager identityManager,
Map<String, String> properties) {
this.name = name;
this.identityManager = identityManager;
this.properties = properties;
}
@Override
public AuthenticationMechanismOutcome authenticate(HttpServerExchange exchange, SecurityContext securityContext) {
AuthenticationMechanismOutcome outcome = AuthenticationMechanismOutcome.NOT_ATTEMPTED;
if(exchange.getRequestHeaders()!=null){
String token = null;
for(String header : IdentityAsserterLoginModule.TOKEN_TYPE){
token = exchange.getRequestHeaders().getFirst(header);
if(token!=null && !token.isEmpty()){
outcome = attemptIdtyAssertion(exchange,securityContext,token);
if(AuthenticationMechanismOutcome.AUTHENTICATED.equals(outcome)){
break;
}
}
}
}
return outcome;
}
private AuthenticationMechanismOutcome attemptIdtyAssertion(HttpServerExchange exchange, SecurityContext securityContext,String token){
String decodedToken = null;
String userName = null;
try {
byte[] decodedTokenBytes = Base64Encoder.decode(token);
decodedToken = new String(decodedTokenBytes);
if (!(decodedToken.startsWith(TOKEN_PREFIX))) {
String error = "IcargoIdentityAsserter received unknown token string \""
+ decodedToken + "\"." + " Expected " + TOKEN_PREFIX + "sessionId";
log.log(error);
return AuthenticationMechanismOutcome.NOT_ATTEMPTED;
}
// extract the username from the token
userName = decodedToken.substring(TOKEN_PREFIX.length());
} catch (EncryptionFailedException e) {
String error = "Could not Decode token string agaist "+IdentityAsserterLoginModule.TOKEN_TYPE+ "for token "+ token;
log.log(error);
return AuthenticationMechanismOutcome.NOT_ATTEMPTED;
}
//exchange.putAttachment(ExternalAuthenticationMechanism.EXTERNAL_PRINCIPAL, userName);
Account account = null;
SecurityContextThreadLocal.getInstance().setHandleType(SecurityContextThreadLocal.IDTY_ASSERTION_HANDLE_TYPE);
try{
account = identityManager.verify(userName, ExternalCredential.INSTANCE);
}finally{
SecurityContextThreadLocal.getInstance().removeHandleType();
}
if(account!=null){
securityContext.authenticationComplete(account, name , false);
return AuthenticationMechanismOutcome.AUTHENTICATED;
}
return AuthenticationMechanismOutcome.NOT_AUTHENTICATED;
}
@Override
public ChallengeResult sendChallenge(HttpServerExchange exchange, SecurityContext securityContext) {
return new ChallengeResult(false);
}
}
3. SSO Handler for SOAP services
public class SSOHandler implements HttpHandler{
private HttpHandler handler;
public SSOHandler(HttpHandler handler){
this.handler=handler;
}
@Override
public void handleRequest(HttpServerExchange exchange) throws Exception {
if(exchange.getRequestHeaders()!=null){
String token = null;
for(String header : IdentityAsserterLoginModule.SSO_TOKEN_TYPE){
token = exchange.getRequestHeaders().getFirst(header);
if(token!=null && !token.isEmpty()){
doExternalLogin(exchange,token);
break;
}
}
}
try{
this.handler.handleRequest(exchange);
}finally{
SecurityContextThreadLocal.getInstance().removeHandleType();
}
}
private void doExternalLogin(HttpServerExchange exchange,String token) throws ServletException{
if(exchange.getSecurityContext().getAuthenticatedAccount()==null){
SecurityContextThreadLocal.getInstance().setHandleType(SecurityContextThreadLocal.SSO_HANDLE_TYPE);
exchange.getSecurityContext().login(token, "");
}
}
}
4. Then i have my login module where i check my custom checks on the tokens supplied and authenticate the requests.