smarter auth handling
This commit is contained in:
parent
caf267fd9a
commit
3bf46413b1
6 changed files with 56 additions and 34 deletions
|
@ -40,7 +40,8 @@ public class J2HtmlResource extends HtmlTemplateResource {
|
||||||
.header("cache-control", cacheControl()) // override default must-revalidate behavior
|
.header("cache-control", cacheControl()) // override default must-revalidate behavior
|
||||||
.header("content-length", Integer.toString(dataBuffer.writePosition()))
|
.header("content-length", Integer.toString(dataBuffer.writePosition()))
|
||||||
.header(CONTENT_TYPE, "text/html; charset=" + getCharset().displayName())
|
.header(CONTENT_TYPE, "text/html; charset=" + getCharset().displayName())
|
||||||
.body(dataBuffer);
|
.body(dataBuffer)
|
||||||
|
.done();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String cacheControl() {
|
protected String cacheControl() {
|
||||||
|
|
|
@ -39,7 +39,9 @@ public class BasicAuthenticationHandler extends LoginAuthenticationHandler imple
|
||||||
}
|
}
|
||||||
userProfile = new BaseUserProfile();
|
userProfile = new BaseUserProfile();
|
||||||
try {
|
try {
|
||||||
authenticate(userProfile, tokens[0], tokens[1], httpRequest);
|
if (authenticate(userProfile, tokens[0], tokens[1], httpRequest)) {
|
||||||
|
context.setAuthenticated(true);
|
||||||
|
}
|
||||||
context.getAttributes().put("userprofile", userProfile);
|
context.getAttributes().put("userprofile", userProfile);
|
||||||
return;
|
return;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
|
@ -23,9 +23,11 @@ public class FormAuthenticationHandler extends LoginAuthenticationHandler implem
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handle(HttpRouterContext context) throws IOException {
|
public void handle(HttpRouterContext context) throws IOException {
|
||||||
|
logger.log(Level.FINE, "request = " + context.getRequest());
|
||||||
UserProfile userProfile = context.getAttributes().get(UserProfile.class, "userprofile");
|
UserProfile userProfile = context.getAttributes().get(UserProfile.class, "userprofile");
|
||||||
if (userProfile != null && userProfile.getUserId() != null) {
|
if (userProfile != null && userProfile.getUserId() != null) {
|
||||||
logger.log(Level.FINE, "user id already set: " + userProfile.getUserId());
|
logger.log(Level.FINE, "user id already set: " + userProfile.getUserId());
|
||||||
|
context.setAuthenticated(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (context.isAuthenticated()) {
|
if (context.isAuthenticated()) {
|
||||||
|
@ -34,29 +36,30 @@ public class FormAuthenticationHandler extends LoginAuthenticationHandler implem
|
||||||
}
|
}
|
||||||
// always add an "anonymous" user profile with a null user ID
|
// always add an "anonymous" user profile with a null user ID
|
||||||
userProfile = new BaseUserProfile();
|
userProfile = new BaseUserProfile();
|
||||||
context.getAttributes().put("userprofile", userProfile);
|
|
||||||
boolean isAuthenticated = false;
|
boolean isAuthenticated = false;
|
||||||
try {
|
try {
|
||||||
Parameter parameter = context.getRequest().getParameter();
|
Parameter parameter = context.getRequest().getParameter();
|
||||||
if (!parameter.containsKey(getUserParameterName(), Parameter.Domain.FORM)) {
|
if (!parameter.containsKey(getUserParameterName(), Parameter.Domain.FORM)) {
|
||||||
logger.log(Level.WARNING, "usernameParameter not set, unable to authenticate");
|
logger.log(Level.WARNING, "username parameter not set, unable to authenticate");
|
||||||
prepareFormAuthentication(context);
|
prepareFormAuthentication(context);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String username = parameter.getAsString(getUserParameterName(), Parameter.Domain.FORM);
|
String username = parameter.getAsString(getUserParameterName(), Parameter.Domain.FORM);
|
||||||
if (!parameter.containsKey(getPasswordParameterName(), Parameter.Domain.FORM)) {
|
if (!parameter.containsKey(getPasswordParameterName(), Parameter.Domain.FORM)) {
|
||||||
logger.log(Level.WARNING, "passwordParameter not set, unable to authenticate");
|
logger.log(Level.WARNING, "password parameter not set, unable to authenticate");
|
||||||
prepareFormAuthentication(context);
|
prepareFormAuthentication(context);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String password = parameter.getAsString(getPasswordParameterName(), Parameter.Domain.FORM);
|
String password = parameter.getAsString(getPasswordParameterName(), Parameter.Domain.FORM);
|
||||||
authenticate(userProfile, username, password, context.getRequest());
|
if (authenticate(userProfile, username, password, context.getRequest())) {
|
||||||
isAuthenticated = true;
|
isAuthenticated = true;
|
||||||
|
}
|
||||||
} catch (ParameterException e) {
|
} catch (ParameterException e) {
|
||||||
logger.log(Level.SEVERE, "parameter error");
|
logger.log(Level.SEVERE, "parameter error");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.log(Level.SEVERE, "authentication error");
|
logger.log(Level.SEVERE, "authentication error");
|
||||||
} finally {
|
} finally {
|
||||||
|
context.getAttributes().put("userprofile", userProfile);
|
||||||
context.setAuthenticated(isAuthenticated);
|
context.setAuthenticated(isAuthenticated);
|
||||||
if (!isAuthenticated) {
|
if (!isAuthenticated) {
|
||||||
prepareFormAuthentication(context);
|
prepareFormAuthentication(context);
|
||||||
|
|
|
@ -2,6 +2,7 @@ package org.xbib.net.http.server.auth;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import org.xbib.net.Authenticator;
|
import org.xbib.net.Authenticator;
|
||||||
|
@ -26,12 +27,12 @@ public class LoginAuthenticationHandler implements HttpHandler {
|
||||||
|
|
||||||
private final SecurityRealm securityRealm;
|
private final SecurityRealm securityRealm;
|
||||||
|
|
||||||
public LoginAuthenticationHandler(String userParameterName,
|
public LoginAuthenticationHandler(String usernameParameterName,
|
||||||
String passwordParameterName,
|
String passwordParameterName,
|
||||||
SecurityRealm securityRealm) {
|
SecurityRealm securityRealm) {
|
||||||
this.userParameterName = userParameterName;
|
this.userParameterName = Objects.requireNonNull(usernameParameterName, "username parameter must not be null");
|
||||||
this.passwordParameterName = passwordParameterName;
|
this.passwordParameterName = Objects.requireNonNull(passwordParameterName, "password parameter must not be null");
|
||||||
this.securityRealm = securityRealm;
|
this.securityRealm = Objects.requireNonNull(securityRealm, "security realm must not be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUserParameterName() {
|
public String getUserParameterName() {
|
||||||
|
@ -49,7 +50,12 @@ public class LoginAuthenticationHandler implements HttpHandler {
|
||||||
@Override
|
@Override
|
||||||
public void handle(HttpRouterContext context) throws IOException {
|
public void handle(HttpRouterContext context) throws IOException {
|
||||||
UserProfile userProfile = context.getAttributes().get(UserProfile.class, "userprofile");
|
UserProfile userProfile = context.getAttributes().get(UserProfile.class, "userprofile");
|
||||||
if (userProfile != null && userProfile.getUserId() != null) {
|
if (userProfile == null) {
|
||||||
|
logger.log(Level.FINE, "no user profile found in context");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (userProfile.getUserId() != null) {
|
||||||
|
logger.log(Level.FINE, "user id already set");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Parameter parameter = context.getRequest().getParameter();
|
Parameter parameter = context.getRequest().getParameter();
|
||||||
|
@ -59,8 +65,9 @@ public class LoginAuthenticationHandler implements HttpHandler {
|
||||||
try {
|
try {
|
||||||
String username = parameter.getAsString(getUserParameterName(), Parameter.Domain.FORM);
|
String username = parameter.getAsString(getUserParameterName(), Parameter.Domain.FORM);
|
||||||
String password = parameter.getAsString(getPasswordParameterName(), Parameter.Domain.FORM);
|
String password = parameter.getAsString(getPasswordParameterName(), Parameter.Domain.FORM);
|
||||||
authenticate(userProfile, username, password, context.getRequest());
|
if (authenticate(userProfile, username, password, context.getRequest())) {
|
||||||
isAuthenticated = true;
|
isAuthenticated = true;
|
||||||
|
}
|
||||||
} catch (ParameterException e) {
|
} catch (ParameterException e) {
|
||||||
logger.log(Level.SEVERE, "parameter error");
|
logger.log(Level.SEVERE, "parameter error");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -70,29 +77,33 @@ public class LoginAuthenticationHandler implements HttpHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void authenticate(UserProfile userProfile, String username, String password, Request request) {
|
protected boolean authenticate(UserProfile userProfile, String username, String password, Request request) {
|
||||||
if (username == null) {
|
if (username == null) {
|
||||||
logger.log(Level.FINE, "no username given for check, doing nothing");
|
logger.log(Level.FINE, "no username given for check, doing nothing");
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
if (password == null) {
|
if (password == null) {
|
||||||
logger.log(Level.FINE, "no password given for check, doing nothing");
|
logger.log(Level.FINE, "no password given for check, doing nothing");
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
Authenticator auth = securityRealm.getAuthenticator();
|
Authenticator auth = securityRealm.getAuthenticator();
|
||||||
Authenticator.Context authContext = new Authenticator.Context(username, password, request);
|
Authenticator.Context authContext = new Authenticator.Context(username, password, request);
|
||||||
if (auth.authenticate(authContext)) {
|
if (auth.authenticate(authContext)) {
|
||||||
|
logger.log(Level.FINE, "authenticated, augmenting user profile with " + authContext.getUsername());
|
||||||
userProfile.setUserId(authContext.getUsername());
|
userProfile.setUserId(authContext.getUsername());
|
||||||
|
UsersProvider.Context userContext = new UsersProvider.Context(username, null);
|
||||||
|
UserDetails userDetails = securityRealm.getUsersProvider().getUserDetails(userContext);
|
||||||
|
userProfile.setEffectiveUserId(userDetails.getEffectiveUserId());
|
||||||
|
userProfile.setName(userDetails.getName());
|
||||||
|
GroupsProvider.Context groupContext = new GroupsProvider.Context(username, null);
|
||||||
|
Collection<String> groups = securityRealm.getGroupsProvider().getGroups(groupContext);
|
||||||
|
for (String group : groups) {
|
||||||
|
userProfile.addRole(group);
|
||||||
|
}
|
||||||
|
logger.log(Level.FINE, "authentication success: userProfile = " + userProfile);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
UsersProvider.Context userContext = new UsersProvider.Context(username, null);
|
logger.log(Level.FINE, "authentication failure");
|
||||||
UserDetails userDetails = securityRealm.getUsersProvider().getUserDetails(userContext);
|
return false;
|
||||||
userProfile.setEffectiveUserId(userDetails.getEffectiveUserId());
|
|
||||||
userProfile.setName(userDetails.getName());
|
|
||||||
GroupsProvider.Context groupContext = new GroupsProvider.Context(username, null);
|
|
||||||
Collection<String> groups = securityRealm.getGroupsProvider().getGroups(groupContext);
|
|
||||||
for (String group : groups) {
|
|
||||||
userProfile.addRole(group);
|
|
||||||
}
|
|
||||||
logger.log(Level.FINE, "authenticate: userProfile = " + userProfile);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -233,6 +233,9 @@ public class HtmlTemplateResource implements HttpServerResource {
|
||||||
|
|
||||||
private static String toOrigin(URL url) {
|
private static String toOrigin(URL url) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
if (url == null) {
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
if (url.getPath() != null) {
|
if (url.getPath() != null) {
|
||||||
sb.append(url.getPath());
|
sb.append(url.getPath());
|
||||||
}
|
}
|
||||||
|
@ -242,7 +245,7 @@ public class HtmlTemplateResource implements HttpServerResource {
|
||||||
if (url.getFragment() != null) {
|
if (url.getFragment() != null) {
|
||||||
sb.append('#').append(url.getFragment());
|
sb.append('#').append(url.getFragment());
|
||||||
}
|
}
|
||||||
if (sb.length() == 0) {
|
if (sb.isEmpty()) {
|
||||||
sb.append('/');
|
sb.append('/');
|
||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
|
|
|
@ -53,9 +53,11 @@ public class GroovyFormAuthenticationHandler extends FormAuthenticationHandler {
|
||||||
String username = parameter.getAsString(getUserParameterName(), Parameter.Domain.FORM);
|
String username = parameter.getAsString(getUserParameterName(), Parameter.Domain.FORM);
|
||||||
String password = parameter.getAsString(getPasswordParameterName(), Parameter.Domain.FORM);
|
String password = parameter.getAsString(getPasswordParameterName(), Parameter.Domain.FORM);
|
||||||
logger.log(Level.FINE, "username and password found, ready for authentication");
|
logger.log(Level.FINE, "username and password found, ready for authentication");
|
||||||
authenticate(userProfile, username, password, context.getRequest());
|
if (authenticate(userProfile, username, password, context.getRequest())) {
|
||||||
logger.log(Level.FINE, "successful authentication");
|
context.setAuthenticated(true);
|
||||||
return;
|
logger.log(Level.FINE, "successful authentication");
|
||||||
|
return;
|
||||||
|
}
|
||||||
} catch (ParameterException e) {
|
} catch (ParameterException e) {
|
||||||
logger.log(Level.SEVERE, "parameter error");
|
logger.log(Level.SEVERE, "parameter error");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -70,8 +72,8 @@ public class GroovyFormAuthenticationHandler extends FormAuthenticationHandler {
|
||||||
// We need a full path resolve against the server URL.
|
// We need a full path resolve against the server URL.
|
||||||
logger.log(Level.FINE, "set new templatePath, login template = " + loginTemplate);
|
logger.log(Level.FINE, "set new templatePath, login template = " + loginTemplate);
|
||||||
context.getAttributes().put("templatePath", loginTemplate);
|
context.getAttributes().put("templatePath", loginTemplate);
|
||||||
URL loc = context.getContextURL().resolve(context.getRequest().getRequestURI()).normalize();
|
URL origin = context.getContextURL().resolve(context.getRequest().getRequestURI()).normalize();
|
||||||
logger.log(Level.FINE, "context URL = " + context.getContextURL() + " request URI = " + context.getRequest().getRequestURI() + " loc = " + loc);
|
logger.log(Level.FINE, "context URL = " + context.getContextURL() + " request URI = " + context.getRequest().getRequestURI() + " origin = " + origin);
|
||||||
context.getAttributes().put("originalPath", loc.toExternalForm());
|
context.getAttributes().put("originalPath", origin.toExternalForm());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue