Skip to content

Commit

Permalink
Added Basic auth to Swagger support.
Browse files Browse the repository at this point in the history
  • Loading branch information
noboomu committed May 23, 2017
1 parent a55b0d6 commit 359d60f
Show file tree
Hide file tree
Showing 3 changed files with 181 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/**
*
*/
package io.sinistral.proteus.server.security;

import java.security.Principal;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import java.util.Set;

import io.undertow.security.idm.Account;
import io.undertow.security.idm.Credential;
import io.undertow.security.idm.IdentityManager;
import io.undertow.security.idm.PasswordCredential;

/**
* @author jbauer
*/
public class MapIdentityManager implements IdentityManager
{

private final Map<String, char[]> identities;

public MapIdentityManager(final Map<String, char[]> identities)
{
this.identities = identities;
}

@Override
public Account verify(Account account)
{
// An existing account so for testing assume still valid.
return account;
}

@Override
public Account verify(String id, Credential credential)
{
Account account = getAccount(id);
if (account != null && verifyCredential(account, credential))
{
return account;
}

return null;
}

@Override
public Account verify(Credential credential)
{
// TODO Auto-generated method stub
return null;
}

private boolean verifyCredential(Account account, Credential credential)
{
if (credential instanceof PasswordCredential)
{
char[] password = ((PasswordCredential) credential).getPassword();
char[] expectedPassword = identities.get(account.getPrincipal().getName());

return Arrays.equals(password, expectedPassword);
}
return false;
}

private Account getAccount(final String id)
{
if (identities.containsKey(id))
{
return new UserAccount(id);
}
return null;
}

private class UserAccount implements Account
{

private static final long serialVersionUID = -8234851531206339721L;

private final Principal principal;

public UserAccount(String id)
{
principal = new Principal()
{

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

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

@Override
public Set<String> getRoles()
{
return Collections.emptySet();
}
}

}
63 changes: 60 additions & 3 deletions src/main/java/io/sinistral/proteus/services/SwaggerService.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
Expand All @@ -37,18 +39,26 @@
import com.typesafe.config.ConfigObject;

import io.sinistral.proteus.server.endpoints.EndpointInfo;
import io.sinistral.proteus.server.swagger.ServerParameterExtension;
import io.sinistral.proteus.server.security.MapIdentityManager;
import io.sinistral.proteus.server.swagger.ServerParameterExtension;
import io.swagger.jaxrs.ext.SwaggerExtension;
import io.swagger.jaxrs.ext.SwaggerExtensions;
import io.swagger.models.Info;
import io.swagger.models.SecurityRequirement;
import io.swagger.models.Swagger;
import io.swagger.models.auth.ApiKeyAuthDefinition;
import io.swagger.models.auth.SecuritySchemeDefinition;
import io.swagger.models.auth.BasicAuthDefinition;
import io.undertow.attribute.ExchangeAttribute;
import io.undertow.attribute.ExchangeAttributes;
import io.undertow.predicate.Predicate;
import io.undertow.predicate.Predicates;
import io.undertow.security.api.AuthenticationMechanism;
import io.undertow.security.api.AuthenticationMode;
import io.undertow.security.handlers.AuthenticationCallHandler;
import io.undertow.security.handlers.AuthenticationConstraintHandler;
import io.undertow.security.handlers.AuthenticationMechanismsHandler;
import io.undertow.security.handlers.SecurityInitialHandler;
import io.undertow.security.idm.IdentityManager;
import io.undertow.security.impl.BasicAuthenticationMechanism;
import io.undertow.server.HandlerWrapper;
import io.undertow.server.HttpHandler;
import io.undertow.server.HttpServerExchange;
Expand Down Expand Up @@ -257,6 +267,53 @@ public HttpHandler wrap(final HttpHandler handler)
}
}
}

if(swaggerSecurity.hasPath("basicRealms"))
{
List<? extends ConfigObject> realms = swaggerSecurity.getObjectList("basicRealms");

for(ConfigObject realm : realms)
{
Config realmConfig = realm.toConfig();

final String name = realmConfig.getString("name");

List<String> identities = realmConfig.getStringList("identities");

final Map<String, char[]> identityMap = new HashMap<>();

identities.stream().forEach( i -> {
String[] identity = i.split(":");

identityMap.put(identity[0], identity[1].toCharArray());
});

final IdentityManager identityManager = new MapIdentityManager(identityMap);

log.debug("Adding basic handler for realm " + name + " with identities " + identityMap);


final HandlerWrapper wrapper = new HandlerWrapper()
{
@Override
public HttpHandler wrap(final HttpHandler handler)
{
HttpHandler authHandler = new AuthenticationCallHandler(handler);
authHandler = new AuthenticationConstraintHandler(authHandler);
final List<AuthenticationMechanism> mechanisms = Collections.<AuthenticationMechanism>singletonList(new BasicAuthenticationMechanism(name));
authHandler = new AuthenticationMechanismsHandler(authHandler, mechanisms);
authHandler = new SecurityInitialHandler(AuthenticationMode.PRO_ACTIVE, identityManager, authHandler);
return authHandler;
}
};

BasicAuthDefinition authDefinition = new BasicAuthDefinition();
swagger.addSecurityDefinition(name, authDefinition);

registeredHandlerWrappers.put(name, wrapper);

}
}


this.reader = new io.sinistral.proteus.server.swagger.Reader(swagger);
Expand Down
11 changes: 11 additions & 0 deletions src/main/resources/reference.conf
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,17 @@ swagger {
value="123456789"
}
]

# basicRealms =
# [
# {
# name = defaultBasic
# identities =
# [
# "username:password"
# ]
# }
# ]
}


Expand Down

0 comments on commit 359d60f

Please sign in to comment.