init
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src/main/java"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/>
|
||||
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>maxkey-authentications</name>
|
||||
<comment>Project maxkey-authentications created by Buildship.</comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.common.project.facet.core.builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.springframework.ide.eclipse.boot.validation.springbootbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.wst.validation.validationbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
|
||||
<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
|
||||
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -0,0 +1,11 @@
|
||||
build.commands=org.eclipse.jdt.core.javabuilder
|
||||
connection.arguments=
|
||||
connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
|
||||
connection.java.home=null
|
||||
connection.jvm.arguments=
|
||||
connection.project.dir=..
|
||||
containers=org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7/
|
||||
derived.resources=.gradle,build
|
||||
eclipse.preferences.version=1
|
||||
natures=org.eclipse.jdt.core.javanature
|
||||
project.path=\:maxkey-authentications
|
||||
@@ -0,0 +1,2 @@
|
||||
eclipse.preferences.version=1
|
||||
encoding/<project>=UTF-8
|
||||
@@ -0,0 +1,24 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.builder.cleanOutputFolder=clean
|
||||
org.eclipse.jdt.core.builder.duplicateResourceTask=warning
|
||||
org.eclipse.jdt.core.builder.invalidClasspath=abort
|
||||
org.eclipse.jdt.core.builder.recreateModifiedClassFileInOutputFolder=ignore
|
||||
org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=
|
||||
org.eclipse.jdt.core.circularClasspath=warning
|
||||
org.eclipse.jdt.core.classpath.exclusionPatterns=enabled
|
||||
org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled
|
||||
org.eclipse.jdt.core.classpath.outputOverlappingAnotherSource=error
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.maxProblemPerUnit=100
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
org.eclipse.jdt.core.incompatibleJDKLevel=ignore
|
||||
org.eclipse.jdt.core.incompleteClasspath=error
|
||||
@@ -0,0 +1,2 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.launching.PREF_STRICTLY_COMPATIBLE_JRE_NOT_AVAILABLE=warning
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
|
||||
<wb-module deploy-name="maxkey-authentications">
|
||||
<wb-resource deploy-path="/" source-path="/src/main/java"/>
|
||||
</wb-module>
|
||||
</project-modules>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<faceted-project>
|
||||
<fixed facet="java"/>
|
||||
<fixed facet="jst.utility"/>
|
||||
<installed facet="jst.utility" version="1.0"/>
|
||||
<installed facet="java" version="1.8"/>
|
||||
</faceted-project>
|
||||
@@ -0,0 +1,2 @@
|
||||
boot.validation.initialized=true
|
||||
eclipse.preferences.version=1
|
||||
@@ -0,0 +1,29 @@
|
||||
|
||||
description = "maxkey-authentications"
|
||||
|
||||
|
||||
dependencies {
|
||||
//local jars
|
||||
compile fileTree(dir: '../maxkey-lib/spring/', include: '*.jar')
|
||||
compile fileTree(dir: '../maxkey-lib/spring-security/', include: '*.jar')
|
||||
compile fileTree(dir: '../maxkey-lib/apache/', include: '*.jar')
|
||||
compile fileTree(dir: '../maxkey-lib/db/', include: '*.jar')
|
||||
compile fileTree(dir: '../maxkey-lib/tiles/', include: '*.jar')
|
||||
compile fileTree(dir: '../maxkey-lib/common/', include: '*.jar')
|
||||
compile fileTree(dir: '../maxkey-lib/opensaml/', include: '*.jar')
|
||||
compile fileTree(dir: '../maxkey-lib/xml/', include: '*.jar')
|
||||
compile fileTree(dir: '../maxkey-lib/json/', include: '*.jar')
|
||||
compile fileTree(dir: '../maxkey-lib/log/', include: '*.jar')
|
||||
compile fileTree(dir: '../maxkey-lib/java/', include: '*.jar')
|
||||
compile fileTree(dir: '../maxkey-lib/other/', include: '*.jar')
|
||||
|
||||
|
||||
|
||||
compile project(":maxkey-core")
|
||||
compile project(":maxkey-dao")
|
||||
compile project(":maxkey-jose-jwt")
|
||||
compile project(":maxkey-client-sdk")
|
||||
compile project(":maxkey-protocols:maxkey-protocol-oauth-2.0")
|
||||
compile project(":maxkey-protocols:maxkey-protocol-saml-2.0")
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
Manifest-Version: 1.0
|
||||
Class-Path:
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
package org.maxkey.authn;
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
package org.maxkey.authn.realm.activedirectory;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import org.maxkey.authn.realm.AbstractAuthenticationRealm;
|
||||
import org.maxkey.authn.realm.IAuthenticationServer;
|
||||
import org.maxkey.domain.UserInfo;
|
||||
import org.maxkey.web.WebContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
|
||||
|
||||
public class ActiveDirectoryAuthenticationRealm extends AbstractAuthenticationRealm{
|
||||
private final static Logger _logger = LoggerFactory.getLogger(ActiveDirectoryAuthenticationRealm.class);
|
||||
|
||||
@NotNull
|
||||
@Size(min=1)
|
||||
private List<IAuthenticationServer> activeDirectoryServers;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public ActiveDirectoryAuthenticationRealm() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param jdbcTemplate
|
||||
*/
|
||||
public ActiveDirectoryAuthenticationRealm(JdbcTemplate jdbcTemplate) {
|
||||
super(jdbcTemplate);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean passwordMatches(UserInfo userInfo, String password) {
|
||||
boolean isAuthenticated=false;
|
||||
for (final IAuthenticationServer activeDirectoryServer : this.activeDirectoryServers) {
|
||||
_logger.debug("Attempting to authenticate {} at {}", userInfo.getUsername(), activeDirectoryServer);
|
||||
isAuthenticated= activeDirectoryServer.authenticate(userInfo.getUsername(), password);
|
||||
if (isAuthenticated ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if(!isAuthenticated){
|
||||
throw new BadCredentialsException(WebContext.getI18nValue("login.error.password"));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public void setActiveDirectoryServers(
|
||||
List<IAuthenticationServer> activeDirectoryServers) {
|
||||
this.activeDirectoryServers = activeDirectoryServers;
|
||||
}
|
||||
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package org.maxkey.authn.realm.activedirectory;
|
||||
|
||||
import org.maxkey.authn.realm.IAuthenticationServer;
|
||||
import org.maxkey.persistence.ldap.ActiveDirectoryUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* @author Crystal.Sea
|
||||
*
|
||||
*/
|
||||
public final class ActiveDirectoryServer implements IAuthenticationServer {
|
||||
private final static Logger _logger = LoggerFactory.getLogger(ActiveDirectoryServer.class);
|
||||
|
||||
ActiveDirectoryUtils activeDirectoryUtils;
|
||||
|
||||
String filter;
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.connsec.web.authentication.realm.IAuthenticationServer#authenticate(java.lang.String, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public boolean authenticate(String username, String password) {
|
||||
ActiveDirectoryUtils ldapPassWordValid = new ActiveDirectoryUtils(activeDirectoryUtils.getProviderUrl(),
|
||||
activeDirectoryUtils.getDomain()+"\\" + username, password,activeDirectoryUtils.getDomain());
|
||||
ldapPassWordValid.openConnection();
|
||||
if(ldapPassWordValid.getCtx()!=null){
|
||||
_logger.debug("Active Directory user " + username + " is validate .");
|
||||
ldapPassWordValid.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
ldapPassWordValid.close();
|
||||
return false;
|
||||
}
|
||||
|
||||
public ActiveDirectoryUtils getActiveDirectoryUtils() {
|
||||
return activeDirectoryUtils;
|
||||
}
|
||||
|
||||
public void setActiveDirectoryUtils(ActiveDirectoryUtils activeDirectoryUtils) {
|
||||
this.activeDirectoryUtils = activeDirectoryUtils;
|
||||
}
|
||||
|
||||
public String getFilter() {
|
||||
return filter;
|
||||
}
|
||||
|
||||
public void setFilter(String filter) {
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
package org.maxkey.authn.realm.ldap;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import org.maxkey.authn.realm.AbstractAuthenticationRealm;
|
||||
import org.maxkey.authn.realm.IAuthenticationServer;
|
||||
import org.maxkey.domain.UserInfo;
|
||||
import org.maxkey.web.WebContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
|
||||
public class LdapAuthenticationRealm extends AbstractAuthenticationRealm{
|
||||
private final static Logger _logger = LoggerFactory.getLogger(LdapAuthenticationRealm.class);
|
||||
|
||||
@NotNull
|
||||
@Size(min=1)
|
||||
private List<IAuthenticationServer> ldapServers;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public LdapAuthenticationRealm() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param jdbcTemplate
|
||||
*/
|
||||
public LdapAuthenticationRealm(JdbcTemplate jdbcTemplate) {
|
||||
super(jdbcTemplate);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean passwordMatches(UserInfo userInfo, String password) {
|
||||
boolean isAuthenticated=false;
|
||||
for (final IAuthenticationServer ldapServer : this.ldapServers) {
|
||||
_logger.debug("Attempting to authenticate {} at {}", userInfo.getUsername(), ldapServer);
|
||||
isAuthenticated= ldapServer.authenticate(userInfo.getUsername(), password);
|
||||
if (isAuthenticated ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if(!isAuthenticated){
|
||||
throw new BadCredentialsException(WebContext.getI18nValue("login.error.password"));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setLdapServers(List<IAuthenticationServer> ldapServers) {
|
||||
this.ldapServers = ldapServers;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package org.maxkey.authn.realm.ldap;
|
||||
|
||||
import javax.naming.NamingEnumeration;
|
||||
import javax.naming.NamingException;
|
||||
import javax.naming.directory.SearchControls;
|
||||
import javax.naming.directory.SearchResult;
|
||||
|
||||
import org.maxkey.authn.realm.IAuthenticationServer;
|
||||
import org.maxkey.persistence.ldap.LdapUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* @author Crystal.Sea
|
||||
*
|
||||
*/
|
||||
public final class LdapServer implements IAuthenticationServer {
|
||||
private final static Logger _logger = LoggerFactory.getLogger(LdapServer.class);
|
||||
|
||||
LdapUtils ldapUtils;
|
||||
|
||||
String filterAttribute;
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see com.connsec.web.authentication.realm.IAuthenticationServer#authenticate(java.lang.String, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public boolean authenticate(String username, String password) {
|
||||
String queryFilter = "("+filterAttribute+"="+username+")";
|
||||
_logger.info(" filter : " + queryFilter);
|
||||
String dn="";
|
||||
SearchControls constraints = new SearchControls();
|
||||
constraints.setSearchScope(ldapUtils.getSearchScope());
|
||||
try {
|
||||
NamingEnumeration<SearchResult> results = ldapUtils.getConnection()
|
||||
.search(ldapUtils.getBaseDN(), queryFilter, constraints);
|
||||
|
||||
if (results == null || !results.hasMore()) {
|
||||
_logger.error("Ldap user "+username +" not found . ");
|
||||
return false;
|
||||
}else{
|
||||
while (results != null && results.hasMore()) {
|
||||
SearchResult sr = (SearchResult) results.next();
|
||||
//String rdn = sr.getName();
|
||||
dn = sr.getNameInNamespace();
|
||||
_logger.debug("Directory user dn is "+dn+" .");
|
||||
}
|
||||
}
|
||||
} catch (NamingException e) {
|
||||
_logger.error("query throw NamingException:" + e.getMessage());
|
||||
} finally {
|
||||
ldapUtils.close();
|
||||
}
|
||||
|
||||
LdapUtils ldapPassWordValid=new LdapUtils(ldapUtils.getProviderUrl(),dn,password);
|
||||
ldapPassWordValid.openConnection();
|
||||
if(ldapPassWordValid.getCtx()!=null){
|
||||
_logger.debug("Directory user " + username + " is validate .");
|
||||
ldapPassWordValid.close();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public LdapUtils getLdapUtils() {
|
||||
return ldapUtils;
|
||||
}
|
||||
public void setLdapUtils(LdapUtils ldapUtils) {
|
||||
this.ldapUtils = ldapUtils;
|
||||
}
|
||||
public String getFilterAttribute() {
|
||||
return filterAttribute;
|
||||
}
|
||||
public void setFilterAttribute(String filterAttribute) {
|
||||
this.filterAttribute = filterAttribute;
|
||||
}
|
||||
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
package org.maxkey.authn.realm.radius;
|
||||
|
||||
/**
|
||||
* RADIUS protocol enumeration.
|
||||
*
|
||||
*/
|
||||
public enum RadiusProtocol {
|
||||
|
||||
/** The chap. */
|
||||
CHAP("chap"),
|
||||
|
||||
/** The EA p_ m d5. */
|
||||
EAP_MD5("eap-md5"),
|
||||
|
||||
/** The EA p_ mscha pv2. */
|
||||
EAP_MSCHAPv2("eap-mschapv2"),
|
||||
|
||||
/** The eap tls. */
|
||||
EAP_TLS("eap-tls"),
|
||||
|
||||
/** The eap ttls pap. */
|
||||
EAP_TTLS_PAP("eap-ttls:innerProtocol=pap"),
|
||||
|
||||
/** The EA p_ ttl s_ ea p_ m d5. */
|
||||
EAP_TTLS_EAP_MD5("eap-ttls:innerProtocol=eap-md5"),
|
||||
|
||||
/** The EA p_ ttl s_ ea p_ mscha pv2. */
|
||||
EAP_TTLS_EAP_MSCHAPv2("eap-ttls:innerProtocol=eap-mschapv2"),
|
||||
|
||||
/** The MSCHA pv1. */
|
||||
MSCHAPv1("mschapv1"),
|
||||
|
||||
/** The MSCHA pv2. */
|
||||
MSCHAPv2("mschapv2"),
|
||||
|
||||
/** The pap. */
|
||||
PAP("pap"),
|
||||
|
||||
/** The peap. */
|
||||
PEAP("peap");
|
||||
|
||||
/** The name. */
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* Instantiates a new radius protocol.
|
||||
*
|
||||
* @param name the name
|
||||
*/
|
||||
RadiusProtocol(final String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the radius protocol name required by {@link net.jradius.client.RadiusClient#getAuthProtocol(String)}.
|
||||
*
|
||||
* @return RADIUS protocol name known to {@link net.jradius.client.RadiusClient}.
|
||||
*/
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,231 @@
|
||||
|
||||
package org.maxkey.authn.realm.radius;
|
||||
|
||||
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import net.jradius.client.RadiusClient;
|
||||
import net.jradius.dictionary.Attr_NASIPAddress;
|
||||
import net.jradius.dictionary.Attr_NASIPv6Address;
|
||||
import net.jradius.dictionary.Attr_NASIdentifier;
|
||||
import net.jradius.dictionary.Attr_NASPort;
|
||||
import net.jradius.dictionary.Attr_NASPortId;
|
||||
import net.jradius.dictionary.Attr_NASPortType;
|
||||
import net.jradius.dictionary.Attr_ReplyMessage;
|
||||
import net.jradius.dictionary.Attr_UserName;
|
||||
import net.jradius.dictionary.Attr_UserPassword;
|
||||
import net.jradius.dictionary.vsa_redback.Attr_NASRealPort;
|
||||
import net.jradius.packet.AccessAccept;
|
||||
import net.jradius.packet.AccessRequest;
|
||||
import net.jradius.packet.RadiusPacket;
|
||||
import net.jradius.packet.attribute.AttributeList;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.maxkey.authn.realm.IAuthenticationServer;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Implementation of a RadiusServer that utilizes the JRadius packages available
|
||||
* at <a href="http://jradius.sf.net">http://jradius.sf.net</a>.
|
||||
*
|
||||
|
||||
*/
|
||||
public final class RadiusServer extends RadiusServerBase implements IAuthenticationServer{
|
||||
|
||||
/** Default retry count, {@value}. */
|
||||
public static final int DEFAULT_RETRY_COUNT = 3;
|
||||
|
||||
/** Logger instance. */
|
||||
private static final Logger _logger = LoggerFactory.getLogger(RadiusServer.class);
|
||||
|
||||
/** RADIUS protocol. */
|
||||
@NotNull
|
||||
private final RadiusProtocol protocol;
|
||||
|
||||
/** Number of times to retry authentication when no response is received. */
|
||||
@Min(0)
|
||||
private int retries = DEFAULT_RETRY_COUNT;
|
||||
|
||||
private String nasIpAddress = null;
|
||||
|
||||
private String nasIpv6Address = null;
|
||||
|
||||
private long nasPort = -1;
|
||||
|
||||
private long nasPortId = -1;
|
||||
|
||||
private long nasIdentifier = -1;
|
||||
|
||||
private long nasRealPort = -1;
|
||||
|
||||
private long nasPortType = -1;
|
||||
|
||||
|
||||
/**
|
||||
* Instantiates a new server implementation
|
||||
* with the radius protocol and client factory specified.
|
||||
*
|
||||
* @param protocol the protocol
|
||||
* @param clientFactory the client factory
|
||||
*/
|
||||
public RadiusServer(final RadiusProtocol protocol) {
|
||||
this.protocol = protocol;
|
||||
}
|
||||
|
||||
|
||||
public boolean authenticate(final String username, final String password) {
|
||||
|
||||
final AttributeList attributeList = new AttributeList();
|
||||
|
||||
attributeList.add(new Attr_UserName(username));
|
||||
attributeList.add(new Attr_UserPassword(password));
|
||||
|
||||
if (StringUtils.isNotBlank(this.nasIpAddress)) {
|
||||
attributeList.add(new Attr_NASIPAddress(this.nasIpAddress));
|
||||
}
|
||||
if (StringUtils.isNotBlank(this.nasIpv6Address)) {
|
||||
attributeList.add(new Attr_NASIPv6Address(this.nasIpv6Address));
|
||||
}
|
||||
|
||||
if (this.nasPort != -1) {
|
||||
attributeList.add(new Attr_NASPort(this.nasPort));
|
||||
}
|
||||
if (this.nasPortId != -1) {
|
||||
attributeList.add(new Attr_NASPortId(this.nasPortId));
|
||||
}
|
||||
if (this.nasIdentifier != -1) {
|
||||
attributeList.add(new Attr_NASIdentifier(this.nasIdentifier));
|
||||
}
|
||||
if (this.nasRealPort != -1) {
|
||||
attributeList.add(new Attr_NASRealPort(this.nasRealPort));
|
||||
}
|
||||
if (this.nasPortType != -1) {
|
||||
attributeList.add(new Attr_NASPortType(this.nasPortType));
|
||||
}
|
||||
|
||||
RadiusClient client = null;
|
||||
try {
|
||||
client = this.newInstance();
|
||||
final AccessRequest request = new AccessRequest(client, attributeList);
|
||||
final RadiusPacket response = client.authenticate(
|
||||
request,
|
||||
RadiusClient.getAuthProtocol(this.protocol.getName()),
|
||||
this.retries);
|
||||
|
||||
_logger.debug("RADIUS response from {}: {}", client.getRemoteInetAddress().getCanonicalHostName(),response.getClass().getName());
|
||||
_logger.debug("Received : \n" + response.toString());
|
||||
_logger.debug("RADIUS Response Identifier : " + response.getIdentifier());
|
||||
_logger.debug("RADIUS Response code : " + response.getCode());
|
||||
|
||||
_logger.debug("RADIUS Response AttributeList : " + response.getAttributes().getAttributeList());
|
||||
|
||||
|
||||
if (response instanceof AccessAccept) {
|
||||
// final AccessAccept acceptedResponse = (AccessAccept) response;
|
||||
// _logger.debug("Accepted Response Message: " + acceptedResponse.CODE);
|
||||
String responseMessage = (String) response.getAttributeValue(Attr_ReplyMessage.TYPE);
|
||||
|
||||
if (responseMessage != null){
|
||||
_logger.debug("Accepted Response Message: " + responseMessage);
|
||||
}
|
||||
return true;
|
||||
}else if(response instanceof net.jradius.packet.AccessReject){
|
||||
_logger.debug("Access Reject ." );
|
||||
}else if (response instanceof net.jradius.packet.PasswordReject){
|
||||
_logger.debug("Password Reject . ");
|
||||
}
|
||||
|
||||
} catch (final Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (client != null) {
|
||||
client.close();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the nas ip address.
|
||||
*
|
||||
* @param nasIpAddress the new nas ip address
|
||||
* @since 4.1
|
||||
*/
|
||||
public void setNasIpAddress(final String nasIpAddress) {
|
||||
this.nasIpAddress = nasIpAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the nas ipv6 address.
|
||||
*
|
||||
* @param nasIpv6Address the new nas ipv6 address
|
||||
* @since 4.1
|
||||
*/
|
||||
public void setNasIpv6Address(final String nasIpv6Address) {
|
||||
this.nasIpv6Address = nasIpv6Address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the nas port.
|
||||
*
|
||||
* @param nasPort the new nas port
|
||||
* @since 4.1
|
||||
*/
|
||||
public void setNasPort(final long nasPort) {
|
||||
this.nasPort = nasPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the nas port id.
|
||||
*
|
||||
* @param nasPortId the new nas port id
|
||||
* @since 4.1
|
||||
*/
|
||||
public void setNasPortId(final long nasPortId) {
|
||||
this.nasPortId = nasPortId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the nas identifier.
|
||||
*
|
||||
* @param nasIdentifier the new nas identifier
|
||||
* @since 4.1
|
||||
*/
|
||||
public void setNasIdentifier(final long nasIdentifier) {
|
||||
this.nasIdentifier = nasIdentifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the nas real port.
|
||||
*
|
||||
* @param nasRealPort the new nas real port
|
||||
* @since 4.1
|
||||
*/
|
||||
public void setNasRealPort(final long nasRealPort) {
|
||||
this.nasRealPort = nasRealPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the nas port type.
|
||||
*
|
||||
* @param nasPortType the new nas port type
|
||||
* @since 4.1
|
||||
*/
|
||||
public void setNasPortType(final long nasPortType) {
|
||||
this.nasPortType = nasPortType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the retries.
|
||||
*
|
||||
* @param retries the new retries
|
||||
* @since 4.1
|
||||
*/
|
||||
public void setRetries(final int retries) {
|
||||
this.retries = retries;
|
||||
}
|
||||
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
package org.maxkey.authn.realm.radius;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import net.jradius.packet.attribute.AttributeFactory;
|
||||
|
||||
import org.maxkey.authn.realm.AbstractAuthenticationRealm;
|
||||
import org.maxkey.authn.realm.IAuthenticationServer;
|
||||
import org.maxkey.domain.UserInfo;
|
||||
import org.maxkey.web.WebContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
|
||||
|
||||
public class RadiusServerAuthenticationRealm extends AbstractAuthenticationRealm{
|
||||
private final static Logger _logger = LoggerFactory.getLogger(RadiusServerAuthenticationRealm.class);
|
||||
|
||||
/** Load the dictionary implementation. */
|
||||
static {
|
||||
AttributeFactory.loadAttributeDictionary("net.jradius.dictionary.AttributeDictionaryImpl");
|
||||
}
|
||||
|
||||
/** Array of RADIUS servers to authenticate against. */
|
||||
@NotNull
|
||||
@Size(min=1)
|
||||
private List<IAuthenticationServer> jradiusServers;
|
||||
|
||||
|
||||
/**
|
||||
* @param ldapCluster
|
||||
*/
|
||||
public RadiusServerAuthenticationRealm() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean passwordMatches(UserInfo userInfo, String password) {
|
||||
boolean isAuthenticated=false;
|
||||
for (final IAuthenticationServer radiusServer : this.jradiusServers) {
|
||||
_logger.debug("Attempting to authenticate {} at {}", userInfo.getUsername(), radiusServer);
|
||||
isAuthenticated= radiusServer.authenticate(userInfo.getUsername(), password);
|
||||
if (isAuthenticated ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if(!isAuthenticated){
|
||||
throw new BadCredentialsException(WebContext.getI18nValue("login.error.password"));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public void setJradiusServers(List<IAuthenticationServer> jradiusServers) {
|
||||
this.jradiusServers = jradiusServers;
|
||||
}
|
||||
|
||||
}
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
|
||||
package org.maxkey.authn.realm.radius;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import net.jradius.client.RadiusClient;
|
||||
|
||||
/**
|
||||
* Factory for creating RADIUS client instances.
|
||||
*
|
||||
*/
|
||||
public class RadiusServerBase {
|
||||
|
||||
/** The port to do accounting on. */
|
||||
@Min(1)
|
||||
private int accountingPort =1813;
|
||||
|
||||
/** The port to do authentication on. */
|
||||
@Min(1)
|
||||
private int authenticationPort = 1812;
|
||||
|
||||
/** Socket timeout in seconds. */
|
||||
@Min(0)
|
||||
private int socketTimeout = 30;
|
||||
|
||||
/** RADIUS server network address. */
|
||||
@NotNull
|
||||
private InetAddress inetAddress;
|
||||
|
||||
/** The shared secret to send to the RADIUS server. */
|
||||
@NotNull
|
||||
private String sharedSecret;
|
||||
|
||||
/**
|
||||
* Sets the RADIUS server accounting port.
|
||||
*
|
||||
* @param port Accounting port number.
|
||||
*/
|
||||
public void setAccountingPort(final int port) {
|
||||
this.accountingPort = port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the RADIUS server authentication port.
|
||||
*
|
||||
* @param port Authentication port number.
|
||||
*/
|
||||
public void setAuthenticationPort(final int port) {
|
||||
this.authenticationPort = port;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the RADIUS server UDP socket timeout.
|
||||
*
|
||||
* @param timeout Timeout in seconds; 0 for no timeout.
|
||||
*/
|
||||
public void setSocketTimeout(final int timeout) {
|
||||
this.socketTimeout = timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* RADIUS server network address.
|
||||
*
|
||||
* @param address Network address as a string.
|
||||
*/
|
||||
public void setInetAddress(final String address) {
|
||||
try {
|
||||
this.inetAddress = InetAddress.getByName(address);
|
||||
} catch (final UnknownHostException e) {
|
||||
throw new RuntimeException("Invalid address " + address);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* RADIUS server authentication shared secret.
|
||||
*
|
||||
* @param secret Shared secret.
|
||||
*/
|
||||
public void setSharedSecret(final String secret) {
|
||||
this.sharedSecret = secret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new RADIUS client instance using factory configuration settings.
|
||||
*
|
||||
* @return New radius client instance.
|
||||
* @throws IOException In case the transport method encounters an error.
|
||||
*/
|
||||
public RadiusClient newInstance() throws IOException {
|
||||
return new RadiusClient(
|
||||
this.inetAddress, this.sharedSecret, this.authenticationPort, this.accountingPort, this.socketTimeout);
|
||||
}
|
||||
}
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
package org.maxkey.authn.support.basic;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.maxkey.constants.LOGINTYPE;
|
||||
import org.maxkey.util.AuthorizationHeaderUtils;
|
||||
import org.maxkey.web.WebContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
|
||||
|
||||
|
||||
public class BasicEntryPoint extends HandlerInterceptorAdapter {
|
||||
private static final Logger _logger = LoggerFactory.getLogger(BasicEntryPoint.class);
|
||||
|
||||
boolean enable;
|
||||
|
||||
String []skipRequestURI={
|
||||
"/oauth/v20/token",
|
||||
"/oauth/v10a/request_token",
|
||||
"/oauth/v10a/access_token"
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {
|
||||
|
||||
if(!enable){
|
||||
return true;
|
||||
}
|
||||
String requestPath=request.getServletPath();
|
||||
_logger.debug("HttpHeader Login Start ...");
|
||||
_logger.info("Request url : "+ request.getRequestURL());
|
||||
_logger.info("Request URI : "+ request.getRequestURI());
|
||||
_logger.info("Request ContextPath : "+ request.getContextPath());
|
||||
_logger.info("Request ServletPath : "+ request.getServletPath());
|
||||
_logger.debug("RequestSessionId : "+ request.getRequestedSessionId());
|
||||
_logger.debug("isRequestedSessionIdValid : "+ request.isRequestedSessionIdValid());
|
||||
_logger.debug("getSession : "+ request.getSession(false));
|
||||
|
||||
for(int i=0;i<skipRequestURI.length;i++){
|
||||
if(skipRequestURI[i].indexOf(requestPath)>-1){
|
||||
_logger.info("skip uri : "+ requestPath);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// session not exists,session timeout,recreate new session
|
||||
if(request.getSession(false) == null) {
|
||||
request.getSession(true);
|
||||
}
|
||||
String basicCredential =request.getHeader(AuthorizationHeaderUtils.AUTHORIZATION_HEADERNAME);
|
||||
_logger.info("getSession.getId : "+ request.getSession().getId());
|
||||
|
||||
_logger.info("Authorization : " + basicCredential);
|
||||
|
||||
|
||||
if(basicCredential==null||basicCredential.equals("")){
|
||||
_logger.info("Authentication fail header Authorization is null . ");
|
||||
return false;
|
||||
}
|
||||
String username=null;
|
||||
String password=null;
|
||||
if(AuthorizationHeaderUtils.isBasic(basicCredential)){
|
||||
String []usernamePassword=AuthorizationHeaderUtils.resolveBasic(basicCredential);
|
||||
username=usernamePassword[0];
|
||||
password=usernamePassword[1];
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
if(username==null||username.equals("")){
|
||||
_logger.info("Authentication fail username is null . ");
|
||||
return false;
|
||||
}
|
||||
if(password==null||password.equals("")){
|
||||
_logger.info("Authentication fail password is null . ");
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isAuthenticated=false;
|
||||
|
||||
if(SecurityContextHolder.getContext().getAuthentication() == null) {
|
||||
_logger.info("Security Authentication is null .");
|
||||
isAuthenticated=false;
|
||||
}else {
|
||||
_logger.info("Security Authentication not null . ");
|
||||
UsernamePasswordAuthenticationToken authenticationToken = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
|
||||
String lastSessionUserName = authenticationToken.getPrincipal().toString();
|
||||
_logger.info("Authentication Principal : " + lastSessionUserName);
|
||||
if (lastSessionUserName != null && !lastSessionUserName.equals(username)) {
|
||||
isAuthenticated=false;
|
||||
}else{
|
||||
isAuthenticated=true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!isAuthenticated){
|
||||
if(WebContext.setAuthentication(username,LOGINTYPE.BASIC,"","","success")){
|
||||
_logger.info("Authentication "+username+" successful .");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param enable the enable to set
|
||||
*/
|
||||
public void setEnable(boolean enable) {
|
||||
this.enable = enable;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package org.maxkey.authn.support.cas;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.jasig.cas.client.util.AbstractCasFilter;
|
||||
import org.jasig.cas.client.validation.Assertion;
|
||||
import org.maxkey.config.ApplicationConfig;
|
||||
import org.maxkey.constants.LOGINTYPE;
|
||||
import org.maxkey.web.WebContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
|
||||
/**
|
||||
* @author Crystal.Sea
|
||||
*
|
||||
*/
|
||||
@Controller
|
||||
public class CasEndpoint {
|
||||
private static Logger _logger = LoggerFactory.getLogger(CasEndpoint.class);
|
||||
|
||||
@Autowired
|
||||
@Qualifier("applicationConfig")
|
||||
protected ApplicationConfig applicationConfig;
|
||||
|
||||
|
||||
/**
|
||||
* init login
|
||||
* @return
|
||||
*/
|
||||
@RequestMapping(value={"/logon/cas"})
|
||||
public ModelAndView casLogin(
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
_logger.debug("CasEndpoint /cas.");
|
||||
|
||||
Assertion assertion = (Assertion) request.getSession().getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION);
|
||||
|
||||
|
||||
String username= assertion.getPrincipal().getName();
|
||||
|
||||
_logger.debug("CAS username : "+username);
|
||||
|
||||
if(WebContext.setAuthentication(username,LOGINTYPE.CAS,"","","success")){
|
||||
|
||||
}
|
||||
|
||||
|
||||
return WebContext.redirect("/login");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package org.maxkey.authn.support.cas;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||
|
||||
public class CasEntryPoint implements AuthenticationEntryPoint {
|
||||
|
||||
private static final Logger _logger = LoggerFactory.getLogger(CasEntryPoint.class);
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.security.web.AuthenticationEntryPoint#commence(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, org.springframework.security.core.AuthenticationException)
|
||||
*/
|
||||
public void commence(HttpServletRequest request, HttpServletResponse response,
|
||||
AuthenticationException ex) throws IOException, ServletException {
|
||||
|
||||
_logger.debug("CasEntryPoint..");
|
||||
}
|
||||
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package org.maxkey.authn.support.httpheader;
|
||||
|
||||
public class HttpHeaderConfig {
|
||||
String headerName;
|
||||
boolean enable;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public HttpHeaderConfig() {
|
||||
|
||||
}
|
||||
public String getHeaderName() {
|
||||
return headerName;
|
||||
}
|
||||
public void setHeaderName(String headerName) {
|
||||
this.headerName = headerName;
|
||||
}
|
||||
public boolean isEnable() {
|
||||
return enable;
|
||||
}
|
||||
public void setEnable(boolean enable) {
|
||||
this.enable = enable;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
package org.maxkey.authn.support.httpheader;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.maxkey.constants.LOGINTYPE;
|
||||
import org.maxkey.web.WebContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
|
||||
|
||||
|
||||
public class HttpHeaderEntryPoint extends HandlerInterceptorAdapter {
|
||||
private static final Logger _logger = LoggerFactory.getLogger(HttpHeaderEntryPoint.class);
|
||||
|
||||
@Autowired
|
||||
@Qualifier("httpHeaderSupport")
|
||||
HttpHeaderConfig httpHeaderSupport;
|
||||
|
||||
String []skipRequestURI={
|
||||
"/oauth/v20/token",
|
||||
"/oauth/v10a/request_token",
|
||||
"/oauth/v10a/access_token"
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request,HttpServletResponse response, Object handler) throws Exception {
|
||||
|
||||
if(!httpHeaderSupport.isEnable()){
|
||||
return true;
|
||||
}
|
||||
String requestPath=request.getServletPath();
|
||||
_logger.debug("HttpHeader Login Start ...");
|
||||
_logger.info("Request url : "+ request.getRequestURL());
|
||||
_logger.info("Request URI : "+ request.getRequestURI());
|
||||
_logger.info("Request ContextPath : "+ request.getContextPath());
|
||||
_logger.info("Request ServletPath : "+ request.getServletPath());
|
||||
_logger.debug("RequestSessionId : "+ request.getRequestedSessionId());
|
||||
_logger.debug("isRequestedSessionIdValid : "+ request.isRequestedSessionIdValid());
|
||||
_logger.debug("getSession : "+ request.getSession(false));
|
||||
|
||||
for(int i=0;i<skipRequestURI.length;i++){
|
||||
if(skipRequestURI[i].indexOf(requestPath)>-1){
|
||||
_logger.info("skip uri : "+ requestPath);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// session not exists,session timeout,recreate new session
|
||||
if(request.getSession(false) == null) {
|
||||
request.getSession(true);
|
||||
}
|
||||
|
||||
_logger.info("getSession.getId : "+ request.getSession().getId());
|
||||
String httpHeaderUsername = request.getHeader(httpHeaderSupport.getHeaderName());
|
||||
|
||||
_logger.info("HttpHeader username : " + httpHeaderUsername);
|
||||
|
||||
|
||||
if(httpHeaderUsername==null||httpHeaderUsername.equals("")){
|
||||
_logger.info("Authentication fail HttpHeader is null . ");
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean isAuthenticated=false;
|
||||
|
||||
if(SecurityContextHolder.getContext().getAuthentication() == null) {
|
||||
_logger.info("Security Authentication is null .");
|
||||
isAuthenticated=false;
|
||||
}else {
|
||||
_logger.info("Security Authentication not null . ");
|
||||
UsernamePasswordAuthenticationToken authenticationToken = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
|
||||
String lastSessionUserName = authenticationToken.getPrincipal().toString();
|
||||
_logger.info("Authentication Principal : " + lastSessionUserName);
|
||||
if (lastSessionUserName != null && !lastSessionUserName.equals(httpHeaderUsername)) {
|
||||
isAuthenticated=false;
|
||||
}else{
|
||||
isAuthenticated=true;
|
||||
}
|
||||
}
|
||||
|
||||
if(!isAuthenticated){
|
||||
if(WebContext.setAuthentication(httpHeaderUsername,LOGINTYPE.HTTPHEADER,"","","success")){
|
||||
_logger.info("Authentication "+httpHeaderUsername+" successful .");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setHttpHeaderSupport(HttpHeaderConfig httpHeaderSupport) {
|
||||
this.httpHeaderSupport = httpHeaderSupport;
|
||||
}
|
||||
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
package org.maxkey.authn.support.kerberos;
|
||||
|
||||
public class KerberosProxy {
|
||||
|
||||
String userdomain;
|
||||
|
||||
String fullUserdomain;
|
||||
|
||||
String crypto;
|
||||
|
||||
String redirectUri;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public KerberosProxy() {
|
||||
super();
|
||||
}
|
||||
|
||||
public String getUserdomain() {
|
||||
return userdomain;
|
||||
}
|
||||
|
||||
public void setUserdomain(String userdomain) {
|
||||
this.userdomain = userdomain.toUpperCase();
|
||||
}
|
||||
|
||||
public String getFullUserdomain() {
|
||||
return fullUserdomain;
|
||||
}
|
||||
|
||||
public void setFullUserdomain(String fullUserdomain) {
|
||||
this.fullUserdomain = fullUserdomain.toUpperCase();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public String getCrypto() {
|
||||
return crypto;
|
||||
}
|
||||
|
||||
public void setCrypto(String crypto) {
|
||||
this.crypto = crypto;
|
||||
}
|
||||
|
||||
public String getRedirectUri() {
|
||||
return redirectUri;
|
||||
}
|
||||
|
||||
public void setRedirectUri(String redirectUri) {
|
||||
this.redirectUri = redirectUri;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "KerberosProxy [userdomain=" + userdomain + ", fullUserdomain="
|
||||
+ fullUserdomain + ", crypto=" + crypto
|
||||
+ ", redirectUri=" + redirectUri + "]";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package org.maxkey.authn.support.kerberos;
|
||||
|
||||
public interface KerberosService {
|
||||
|
||||
public boolean login(String kerberosTokenString,String kerberosUserDomain);
|
||||
|
||||
public String buildKerberosProxys( );
|
||||
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
package org.maxkey.authn.support.kerberos;
|
||||
|
||||
|
||||
public class KerberosToken {
|
||||
|
||||
private String principal;
|
||||
|
||||
private String fullPrincipal;
|
||||
|
||||
private String notOnOrAfter;
|
||||
|
||||
private String userDomain;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public KerberosToken() {
|
||||
super();
|
||||
}
|
||||
|
||||
public String getPrincipal() {
|
||||
return principal;
|
||||
}
|
||||
|
||||
public void setPrincipal(String principal) {
|
||||
this.principal = principal;
|
||||
}
|
||||
|
||||
public String getFullPrincipal() {
|
||||
return fullPrincipal;
|
||||
}
|
||||
|
||||
public void setFullPrincipal(String fullPrincipal) {
|
||||
this.fullPrincipal = fullPrincipal;
|
||||
}
|
||||
|
||||
public String getNotOnOrAfter() {
|
||||
return notOnOrAfter;
|
||||
}
|
||||
|
||||
public void setNotOnOrAfter(String notOnOrAfter) {
|
||||
this.notOnOrAfter = notOnOrAfter;
|
||||
}
|
||||
|
||||
public String getUserDomain() {
|
||||
return userDomain;
|
||||
}
|
||||
|
||||
public void setUserDomain(String userDomain) {
|
||||
this.userDomain = userDomain;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "KerberosToken [principal=" + principal + ", fullPrincipal="
|
||||
+ fullPrincipal + ", notOnOrAfter=" + notOnOrAfter
|
||||
+ ", userDomain=" + userDomain + "]";
|
||||
}
|
||||
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
package org.maxkey.authn.support.kerberos;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.maxkey.constants.LOGINTYPE;
|
||||
import org.maxkey.crypto.ReciprocalUtils;
|
||||
import org.maxkey.util.DateUtils;
|
||||
import org.maxkey.util.JsonUtils;
|
||||
import org.maxkey.web.WebContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class RemoteKerberosService implements KerberosService{
|
||||
private static Logger _logger = LoggerFactory.getLogger(RemoteKerberosService.class);
|
||||
List<KerberosProxy> kerberosProxys;
|
||||
|
||||
public boolean login(String kerberosTokenString,String kerberosUserDomain){
|
||||
_logger.debug("encoder Kerberos Token "+kerberosTokenString);
|
||||
_logger.debug("kerberos UserDomain "+kerberosUserDomain);
|
||||
|
||||
String decoderKerberosToken=null;
|
||||
for(KerberosProxy kerberosProxy : kerberosProxys){
|
||||
if(kerberosProxy.getUserdomain().equalsIgnoreCase(kerberosUserDomain)){
|
||||
decoderKerberosToken=ReciprocalUtils.aesDecoder(kerberosTokenString, kerberosProxy.getCrypto());
|
||||
break;
|
||||
}
|
||||
}
|
||||
_logger.debug("decoder Kerberos Token "+decoderKerberosToken);
|
||||
KerberosToken kerberosToken=new KerberosToken();
|
||||
kerberosToken=(KerberosToken)JsonUtils.json2Object(decoderKerberosToken, kerberosToken);
|
||||
_logger.debug("Kerberos Token "+kerberosToken);
|
||||
|
||||
DateTime notOnOrAfter=DateUtils.toUtcDate(kerberosToken.getNotOnOrAfter());
|
||||
_logger.debug("Kerberos Token is After Now "+notOnOrAfter.isAfterNow());
|
||||
if(notOnOrAfter.isAfterNow()){
|
||||
return WebContext.setAuthentication(kerberosToken.getPrincipal(),LOGINTYPE.KERBEROS,kerberosUserDomain,"","success");
|
||||
}else{
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public List<KerberosProxy> getKerberosProxys() {
|
||||
return kerberosProxys;
|
||||
}
|
||||
|
||||
public void setKerberosProxys(List<KerberosProxy> kerberosProxys) {
|
||||
this.kerberosProxys = kerberosProxys;
|
||||
}
|
||||
|
||||
public String buildKerberosProxys(){
|
||||
List<Map<String,String>>userDomainUrlList=new ArrayList<Map<String,String>>();
|
||||
for (KerberosProxy kerberosProxy :kerberosProxys){
|
||||
Map<String,String> userDomainUrl =new HashMap<String,String>();
|
||||
userDomainUrl.put("userDomain", kerberosProxy.getUserdomain());
|
||||
userDomainUrl.put("redirectUri", kerberosProxy.getRedirectUri());
|
||||
userDomainUrlList.add(userDomainUrl);
|
||||
}
|
||||
_logger.debug(""+userDomainUrlList);
|
||||
String userDomainUrlJson=JsonUtils.object2Json(userDomainUrlList);
|
||||
_logger.debug("userDomain Url Json "+userDomainUrlJson);
|
||||
return userDomainUrlJson;
|
||||
}
|
||||
}
|
||||
+167
@@ -0,0 +1,167 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package org.maxkey.authn.support.socialsignon;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.maxkey.authn.support.socialsignon.service.SocialSignOnProvider;
|
||||
import org.maxkey.authn.support.socialsignon.service.SocialSignOnProviderService;
|
||||
import org.maxkey.authn.support.socialsignon.service.SocialSignOnUserTokenService;
|
||||
import org.maxkey.client.http.HttpVerb;
|
||||
import org.maxkey.client.http.Response;
|
||||
import org.maxkey.client.oauth.model.OAuthRequest;
|
||||
import org.maxkey.client.oauth.model.Token;
|
||||
import org.maxkey.client.oauth.model.Verifier;
|
||||
import org.maxkey.client.oauth.oauth.OAuthService;
|
||||
import org.maxkey.util.JsonUtils;
|
||||
import org.maxkey.util.StringUtils;
|
||||
import org.maxkey.web.WebContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
* @author Crystal.Sea
|
||||
*
|
||||
*/
|
||||
public class AbstractSocialSignOnEndpoint {
|
||||
final static Logger _logger = LoggerFactory.getLogger(AbstractSocialSignOnEndpoint.class);
|
||||
|
||||
protected final static String SOCIALSIGNON_SESSION_REDIRECT_URI="socialsignon_session_redirect_uri";
|
||||
|
||||
protected final static String SOCIALSIGNON_REDIRECT_URI="redirect_uri";
|
||||
|
||||
public final static String SOCIALSIGNON_TYPE_SESSION="socialsignon_type_session";
|
||||
|
||||
public final static String SOCIALSIGNON_OAUTH_SERVICE_SESSION="socialsignon_oauth_service_session";
|
||||
|
||||
public final static String SOCIALSIGNON_PROVIDER_SESSION="socialsignon_provider_session";
|
||||
|
||||
|
||||
public final static class SOCIALSIGNON_TYPE{
|
||||
public final static String SOCIALSIGNON_TYPE_LOGON="socialsignon_type_logon";
|
||||
public final static String SOCIALSIGNON_TYPE_BIND="socialsignon_type_bind";
|
||||
}
|
||||
|
||||
protected Token accessToken;
|
||||
|
||||
protected SocialSignOnProvider socialSignOnProvider;
|
||||
|
||||
protected OAuthService oauthService;
|
||||
|
||||
protected String accountJsonString;
|
||||
|
||||
protected String accountId;
|
||||
|
||||
protected String provider;
|
||||
|
||||
@Autowired
|
||||
protected SocialSignOnProviderService socialSignOnProviderService;
|
||||
|
||||
@Autowired
|
||||
protected SocialSignOnUserTokenService socialSignOnUserTokenService;
|
||||
|
||||
|
||||
|
||||
protected OAuthService buildOAuthService(String provider){
|
||||
|
||||
SocialSignOnProvider socialSignOnProvider = socialSignOnProviderService.get(provider);
|
||||
_logger.debug("socialSignOn Provider : "+socialSignOnProvider);
|
||||
|
||||
if(socialSignOnProvider!=null){
|
||||
OAuthServiceBuilder oAuthServiceBuilder=new OAuthServiceBuilder(socialSignOnProvider);
|
||||
oauthService=oAuthServiceBuilder.builderOAuthService();
|
||||
WebContext.setAttribute(SOCIALSIGNON_OAUTH_SERVICE_SESSION, socialSignOnProvider);
|
||||
WebContext.setAttribute(SOCIALSIGNON_PROVIDER_SESSION, oauthService);
|
||||
return oauthService;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* get accessToken
|
||||
* @param service
|
||||
* @return
|
||||
*/
|
||||
protected Token getAccessToken() {
|
||||
|
||||
socialSignOnProvider=(SocialSignOnProvider)WebContext.getAttribute(SOCIALSIGNON_OAUTH_SERVICE_SESSION);
|
||||
oauthService=(OAuthService)WebContext.getAttribute(SOCIALSIGNON_PROVIDER_SESSION);
|
||||
String oauthVerifier = WebContext.getRequest().getParameter(socialSignOnProvider.getVerifierCode());
|
||||
WebContext.removeAttribute(SOCIALSIGNON_OAUTH_SERVICE_SESSION);
|
||||
WebContext.removeAttribute(SOCIALSIGNON_PROVIDER_SESSION);
|
||||
if(StringUtils.isNullOrBlank(socialSignOnProvider.getVerifierCode()))
|
||||
return null;
|
||||
// getting access token
|
||||
Verifier verifier = new Verifier(oauthVerifier);
|
||||
this.accessToken=oauthService.getAccessToken(null, verifier);
|
||||
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
protected String requestAccountJson() {
|
||||
OAuthRequest oauthRequest = new OAuthRequest(HttpVerb.GET, this.convertAccountUrl(socialSignOnProvider.getAccountUrl(),socialSignOnProvider.getProvider(), accessToken));
|
||||
oauthService.signRequest(accessToken, oauthRequest);
|
||||
Response oauthResponse = oauthRequest.send();
|
||||
accountJsonString=oauthResponse.getBody();
|
||||
_logger.debug("requestAccountJson : "+accountJsonString);
|
||||
return accountJsonString;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected String getAccountId() {
|
||||
//if(StringUtils.isNullOrBlank(accountJsonString)) {
|
||||
requestAccountJson();
|
||||
//}
|
||||
|
||||
if(this.provider.equals("qq")){
|
||||
accountJsonString=accountJsonString.substring(accountJsonString.indexOf("{"), accountJsonString.indexOf("}")+1);
|
||||
}
|
||||
Map<String,Object> map = new HashMap<String,Object>();
|
||||
|
||||
map=(HashMap<String,Object>)JsonUtils.json2Object(accountJsonString, map);
|
||||
if(this.provider.equals("qqweibo")){
|
||||
if(accessToken.getResponseObject().get(socialSignOnProvider.getAccountId())!=null){
|
||||
accountId=accessToken.getResponseObject().get(socialSignOnProvider.getAccountId()).toString();
|
||||
}
|
||||
}else if(this.provider.equals("qq")){
|
||||
accountId=map.get(socialSignOnProvider.getAccountId()).toString();
|
||||
|
||||
}else{
|
||||
if(map.get(socialSignOnProvider.getAccountId())!=null){
|
||||
accountId=map.get(socialSignOnProvider.getAccountId()).toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_logger.debug("getAccountId : "+accountId);
|
||||
return accountId;
|
||||
}
|
||||
|
||||
private String convertAccountUrl(String accountUrl,String provider,Token accessToken) {
|
||||
if("sinaweibo".equals(provider)) {
|
||||
if(null!=accessToken.getResponseObject()) {
|
||||
Object uid = accessToken.getResponseObject().get("uid");
|
||||
accountUrl = this.convertUrl(accountUrl, "uid", uid == null ? "" : uid.toString());
|
||||
}
|
||||
}
|
||||
return accountUrl;
|
||||
}
|
||||
|
||||
private String convertUrl(String url,String paramName,String paramVal) {
|
||||
StringBuilder sb = new StringBuilder(url);
|
||||
if (url.indexOf('?') < 0) {
|
||||
sb.append('?');
|
||||
}
|
||||
else {
|
||||
sb.append('&');
|
||||
}
|
||||
sb.append(paramName+"=").append(paramVal);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
package org.maxkey.authn.support.socialsignon;
|
||||
|
||||
import org.maxkey.authn.support.socialsignon.service.SocialSignOnProvider;
|
||||
import org.maxkey.client.http.SignatureType;
|
||||
import org.maxkey.client.oauth.builder.ServiceBuilder;
|
||||
import org.maxkey.client.oauth.builder.api.Api;
|
||||
import org.maxkey.client.oauth.builder.api.OAuthApi20;
|
||||
import org.maxkey.client.oauth.oauth.OAuthService;
|
||||
import org.maxkey.web.WebContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class OAuthServiceBuilder {
|
||||
private static Logger _logger = LoggerFactory.getLogger(OAuthServiceBuilder.class);
|
||||
|
||||
private SocialSignOnProvider socialSignOnProvider;
|
||||
|
||||
private Api api;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public OAuthServiceBuilder() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param socialSignOnProvider
|
||||
*/
|
||||
public OAuthServiceBuilder(SocialSignOnProvider socialSignOnProvider) {
|
||||
|
||||
this.socialSignOnProvider = socialSignOnProvider;
|
||||
String callbackUrl=WebContext.getHttpContextPath()+ "/logon/oauth20/callback/"+socialSignOnProvider.getProvider();
|
||||
|
||||
socialSignOnProvider.setCallBack(callbackUrl);
|
||||
|
||||
api = new OAuthApi20(socialSignOnProvider.getAuthorizeUrl(),
|
||||
socialSignOnProvider.getAccessTokenUrl(),
|
||||
socialSignOnProvider.getAccessTokenMethod());
|
||||
|
||||
_logger.debug("api : "+api);
|
||||
}
|
||||
|
||||
|
||||
public OAuthService builderOAuthService() {
|
||||
|
||||
if(socialSignOnProvider.getScope()==null||socialSignOnProvider.getScope().equals("")){
|
||||
return new ServiceBuilder().provider(api)
|
||||
.apiKey(socialSignOnProvider.getClientId())
|
||||
.apiSecret(socialSignOnProvider.getClientSecret())
|
||||
.callback(socialSignOnProvider.getCallBack())
|
||||
.signatureType(SignatureType.QueryString)
|
||||
.debug()
|
||||
.build();
|
||||
}else{
|
||||
return new ServiceBuilder().provider(api)
|
||||
.apiKey(socialSignOnProvider.getClientId())
|
||||
.apiSecret(socialSignOnProvider.getClientSecret())
|
||||
.scope(socialSignOnProvider.getScope())
|
||||
.callback(socialSignOnProvider.getCallBack())
|
||||
.signatureType(SignatureType.QueryString)
|
||||
.debug()
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public SocialSignOnProvider getSocialSignOnProvider() {
|
||||
return socialSignOnProvider;
|
||||
}
|
||||
|
||||
|
||||
public void setSocialSignOnProvider(SocialSignOnProvider socialSignOnProvider) {
|
||||
this.socialSignOnProvider = socialSignOnProvider;
|
||||
}
|
||||
|
||||
|
||||
public Api getApi() {
|
||||
return api;
|
||||
}
|
||||
|
||||
|
||||
public void setApi(Api api) {
|
||||
this.api = api;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+154
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package org.maxkey.authn.support.socialsignon;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.maxkey.authn.realm.AbstractAuthenticationRealm;
|
||||
import org.maxkey.authn.support.socialsignon.service.SocialSignOnUserToken;
|
||||
import org.maxkey.constants.LOGINTYPE;
|
||||
import org.maxkey.util.JsonUtils;
|
||||
import org.maxkey.web.WebContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.security.web.WebAttributes;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
/**
|
||||
* @author Crystal.Sea
|
||||
*
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping(value = "/logon/oauth20")
|
||||
public class SocialSignOnEndpoint extends AbstractSocialSignOnEndpoint{
|
||||
final static Logger _logger = LoggerFactory.getLogger(SocialSignOnEndpoint.class);
|
||||
|
||||
@Autowired
|
||||
@Qualifier("authenticationRealm")
|
||||
protected AbstractAuthenticationRealm authenticationRealm;
|
||||
|
||||
|
||||
public ModelAndView socialSignOnAuthorize(String provider){
|
||||
_logger.debug("SocialSignOn provider : "+provider);
|
||||
String authorizationUrl=buildOAuthService(provider).getAuthorizationUrl(null);
|
||||
_logger.debug("authorize SocialSignOn : "+authorizationUrl);
|
||||
return WebContext.redirect(authorizationUrl);
|
||||
}
|
||||
|
||||
@RequestMapping(value={"/authorize/{provider}"}, method = RequestMethod.GET)
|
||||
public ModelAndView authorize(@PathVariable String provider) {
|
||||
WebContext.setAttribute(SOCIALSIGNON_TYPE_SESSION, SOCIALSIGNON_TYPE.SOCIALSIGNON_TYPE_LOGON);
|
||||
return socialSignOnAuthorize(provider);
|
||||
}
|
||||
|
||||
@RequestMapping(value={"/bind/{provider}"}, method = RequestMethod.GET)
|
||||
public ModelAndView bind(HttpServletRequest request,
|
||||
@PathVariable String provider) {
|
||||
WebContext.setAttribute(SOCIALSIGNON_SESSION_REDIRECT_URI, request.getParameter(SOCIALSIGNON_REDIRECT_URI));
|
||||
WebContext.setAttribute(SOCIALSIGNON_TYPE_SESSION, SOCIALSIGNON_TYPE.SOCIALSIGNON_TYPE_BIND);
|
||||
return socialSignOnAuthorize(provider);
|
||||
}
|
||||
|
||||
@RequestMapping(value={"/unbind/{provider}"}, method = RequestMethod.GET)
|
||||
public ModelAndView unbind(HttpServletRequest request,
|
||||
@PathVariable String provider) {
|
||||
WebContext.setAttribute(SOCIALSIGNON_SESSION_REDIRECT_URI, request.getParameter(SOCIALSIGNON_REDIRECT_URI));
|
||||
SocialSignOnUserToken socialSignOnUser =new SocialSignOnUserToken();
|
||||
socialSignOnUser.setProvider(provider);
|
||||
socialSignOnUser.setUid(WebContext.getUserInfo().getId());
|
||||
socialSignOnUser.setUsername(WebContext.getUserInfo().getUsername());
|
||||
_logger.debug("Social Sign On unbind "+provider+" from user "+WebContext.getUserInfo().getUsername());
|
||||
|
||||
socialSignOnUserTokenService.delete(socialSignOnUser);
|
||||
|
||||
if(WebContext.getAttribute(SOCIALSIGNON_SESSION_REDIRECT_URI)!=null){
|
||||
return WebContext.redirect(WebContext.getAttribute(SOCIALSIGNON_SESSION_REDIRECT_URI).toString());
|
||||
}else{
|
||||
return WebContext.forward("/socialsignon/list");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@RequestMapping(value={"/authorize/{provider}/{appid}"}, method = RequestMethod.GET)
|
||||
public ModelAndView authorize2AppId(@PathVariable("provider") String provider,
|
||||
@PathVariable("appid") String appid) {
|
||||
WebContext.setAttribute(SOCIALSIGNON_SESSION_REDIRECT_URI, "/authorize/"+appid);
|
||||
return authorize(provider);
|
||||
}
|
||||
|
||||
|
||||
@RequestMapping(value={"/callback/{provider}"}, method = RequestMethod.GET)
|
||||
public ModelAndView callback(@PathVariable String provider
|
||||
) {
|
||||
this.provider=provider;
|
||||
this.getAccessToken();
|
||||
this.getAccountId();
|
||||
_logger.debug(this.accountId);
|
||||
SocialSignOnUserToken socialSignOnUserToken =new SocialSignOnUserToken();
|
||||
socialSignOnUserToken.setProvider(provider);
|
||||
socialSignOnUserToken.setSocialuid(this.accountId);
|
||||
|
||||
//for login
|
||||
String socialSignOnType= "";
|
||||
if(WebContext.getAttribute(SOCIALSIGNON_TYPE_SESSION)!=null){
|
||||
socialSignOnType=WebContext.getAttribute(SOCIALSIGNON_TYPE_SESSION).toString();
|
||||
}
|
||||
|
||||
if(socialSignOnType.equals(SOCIALSIGNON_TYPE.SOCIALSIGNON_TYPE_LOGON)||socialSignOnType.equals("")){
|
||||
socialSignOn(socialSignOnUserToken);
|
||||
return WebContext.redirect("/index");
|
||||
}else{
|
||||
socialBind(socialSignOnUserToken);
|
||||
}
|
||||
|
||||
if(WebContext.getAttribute(SOCIALSIGNON_SESSION_REDIRECT_URI)!=null){
|
||||
return WebContext.redirect(WebContext.getAttribute(SOCIALSIGNON_SESSION_REDIRECT_URI).toString());
|
||||
}else{
|
||||
return WebContext.forward("/socialsignon/list");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean socialBind(SocialSignOnUserToken socialSignOnUserToken){
|
||||
socialSignOnUserToken.setSocialUserInfo(accountJsonString);
|
||||
socialSignOnUserToken.setUid(WebContext.getUserInfo().getId());
|
||||
socialSignOnUserToken.setUsername(WebContext.getUserInfo().getUsername());
|
||||
socialSignOnUserToken.setAccessToken(JsonUtils.object2Json(accessToken));
|
||||
socialSignOnUserToken.setExAttribute(JsonUtils.object2Json(accessToken.getResponseObject()));
|
||||
_logger.debug("Social Bind : "+socialSignOnUserToken);
|
||||
this.socialSignOnUserTokenService.delete(socialSignOnUserToken);
|
||||
this.socialSignOnUserTokenService.insert(socialSignOnUserToken);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean socialSignOn(SocialSignOnUserToken socialSignOnUserToken){
|
||||
|
||||
socialSignOnUserToken=this.socialSignOnUserTokenService.get(socialSignOnUserToken);
|
||||
|
||||
_logger.debug("callback SocialSignOn User Token : "+socialSignOnUserToken);
|
||||
if(null !=socialSignOnUserToken){
|
||||
|
||||
_logger.debug("Social Sign On from "+socialSignOnUserToken.getProvider()+" mapping to user "+socialSignOnUserToken.getUsername());
|
||||
|
||||
if(WebContext.setAuthentication(socialSignOnUserToken.getUsername(), LOGINTYPE.SOCIALSIGNON,this.socialSignOnProvider.getProviderName(),"xe00000004","success")){
|
||||
socialSignOnUserToken.setAccessToken(JsonUtils.object2Json(this.accessToken));
|
||||
socialSignOnUserToken.setSocialUserInfo(accountJsonString);
|
||||
socialSignOnUserToken.setExAttribute(JsonUtils.object2Json(accessToken.getResponseObject()));
|
||||
|
||||
this.socialSignOnUserTokenService.update(socialSignOnUserToken);
|
||||
}
|
||||
|
||||
}else{
|
||||
WebContext.getRequest().getSession().setAttribute(WebAttributes.AUTHENTICATION_EXCEPTION, new BadCredentialsException(WebContext.getI18nValue("login.error.social")));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
package org.maxkey.authn.support.socialsignon.service;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
|
||||
public class JdbcSocialSignOnUserTokenService implements SocialSignOnUserTokenService{
|
||||
private static final Logger _logger = LoggerFactory.getLogger(JdbcSocialSignOnUserTokenService.class);
|
||||
|
||||
private static final String DEFAULT_DEFAULT_INSERT_STATEMENT = "INSERT INTO SOCIALSIGNON_USERS_TOKEN(ID, UID , USERNAME , PROVIDER , SOCIALUID , ACCESSTOKEN , SOCIALUSERINFO , EXATTRIBUTE )VALUES( ? , ? , ? , ? , ?, ? , ? , ?)";
|
||||
|
||||
private static final String DEFAULT_DEFAULT_SIGNON_SELECT_STATEMENT = "SELECT ID, UID , USERNAME , PROVIDER , SOCIALUID , ACCESSTOKEN , SOCIALUSERINFO , EXATTRIBUTE FROM SOCIALSIGNON_USERS_TOKEN WHERE PROVIDER = ? AND SOCIALUID = ?";
|
||||
|
||||
private static final String DEFAULT_DEFAULT_BIND_SELECT_STATEMENT = "SELECT ID, UID , USERNAME , PROVIDER , SOCIALUID , ACCESSTOKEN , SOCIALUSERINFO , EXATTRIBUTE FROM SOCIALSIGNON_USERS_TOKEN WHERE UID = ?" ;
|
||||
|
||||
private static final String DEFAULT_DEFAULT_DELETE_STATEMENT = "DELETE FROM SOCIALSIGNON_USERS_TOKEN WHERE UID = ? AND PROVIDER = ?";
|
||||
|
||||
private static final String DEFAULT_DEFAULT_UPDATE_STATEMENT= "UPDATE SOCIALSIGNON_USERS_TOKEN SET ACCESSTOKEN = ? , SOCIALUSERINFO = ? , EXATTRIBUTE = ? ,UPDATEDDATE = ? WHERE ID = ?";
|
||||
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
|
||||
public JdbcSocialSignOnUserTokenService(JdbcTemplate jdbcTemplate) {
|
||||
this.jdbcTemplate=jdbcTemplate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean insert(SocialSignOnUserToken socialSignOnUserToken) {
|
||||
socialSignOnUserToken.setId(socialSignOnUserToken.generateId());
|
||||
jdbcTemplate.update(DEFAULT_DEFAULT_INSERT_STATEMENT,
|
||||
new Object[] {
|
||||
socialSignOnUserToken.getId(),
|
||||
socialSignOnUserToken.getUid(),
|
||||
socialSignOnUserToken.getUsername(),
|
||||
socialSignOnUserToken.getProvider(),
|
||||
socialSignOnUserToken.getSocialuid(),
|
||||
socialSignOnUserToken.getAccessToken(),
|
||||
socialSignOnUserToken.getSocialUserInfo(),
|
||||
socialSignOnUserToken.getExAttribute()},
|
||||
new int[] {Types.VARCHAR, Types.VARCHAR,Types.VARCHAR,Types.VARCHAR, Types.VARCHAR,Types.VARCHAR, Types.VARCHAR,Types.VARCHAR });
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean delete(SocialSignOnUserToken socialSignOnUserToken) {
|
||||
jdbcTemplate.update(DEFAULT_DEFAULT_DELETE_STATEMENT,
|
||||
new Object[] {
|
||||
socialSignOnUserToken.getUid(),
|
||||
socialSignOnUserToken.getProvider()
|
||||
},
|
||||
new int[] {Types.VARCHAR, Types.VARCHAR});
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SocialSignOnUserToken get(SocialSignOnUserToken socialSignOnUserToken) {
|
||||
List<SocialSignOnUserToken> listSocialSignOnUserToken=jdbcTemplate.query(
|
||||
DEFAULT_DEFAULT_SIGNON_SELECT_STATEMENT,
|
||||
new SocialSignOnUserTokenRowMapper(),
|
||||
socialSignOnUserToken.getProvider(),
|
||||
socialSignOnUserToken.getSocialuid());
|
||||
_logger.debug("list SocialSignOnUserToken "+listSocialSignOnUserToken);
|
||||
return (listSocialSignOnUserToken.size()>0)?listSocialSignOnUserToken.get(0):null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SocialSignOnUserToken> query(
|
||||
SocialSignOnUserToken socialSignOnUserToken) {
|
||||
List<SocialSignOnUserToken> listSocialSignOnUserToken=jdbcTemplate.query(
|
||||
DEFAULT_DEFAULT_BIND_SELECT_STATEMENT,
|
||||
new SocialSignOnUserTokenRowMapper(),
|
||||
socialSignOnUserToken.getUid());
|
||||
_logger.debug("query bind SocialSignOnUser "+listSocialSignOnUserToken);
|
||||
return listSocialSignOnUserToken;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean update(SocialSignOnUserToken socialSignOnUserToken) {
|
||||
jdbcTemplate.update(DEFAULT_DEFAULT_UPDATE_STATEMENT,
|
||||
new Object[] {socialSignOnUserToken.getAccessToken(),socialSignOnUserToken.getSocialUserInfo(),socialSignOnUserToken.getExAttribute(),new Date(),socialSignOnUserToken.getId()},
|
||||
new int[] {Types.VARCHAR, Types.VARCHAR,Types.VARCHAR, Types.TIMESTAMP,Types.VARCHAR });
|
||||
return false;
|
||||
}
|
||||
|
||||
private final class SocialSignOnUserTokenRowMapper implements RowMapper<SocialSignOnUserToken> {
|
||||
@Override
|
||||
public SocialSignOnUserToken mapRow(ResultSet rs, int rowNum)
|
||||
throws SQLException {
|
||||
SocialSignOnUserToken socialSignOnUserToken=new SocialSignOnUserToken();
|
||||
socialSignOnUserToken.setId(rs.getString(1));
|
||||
socialSignOnUserToken.setUid(rs.getString(2));
|
||||
socialSignOnUserToken.setUsername(rs.getString(3));
|
||||
socialSignOnUserToken.setProvider(rs.getString(4));
|
||||
socialSignOnUserToken.setSocialuid(rs.getString(5));
|
||||
socialSignOnUserToken.setAccessToken(rs.getString(6));
|
||||
socialSignOnUserToken.setSocialUserInfo(rs.getString(7));
|
||||
socialSignOnUserToken.setExAttribute(rs.getString(8));
|
||||
return socialSignOnUserToken;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
package org.maxkey.authn.support.socialsignon.service;
|
||||
|
||||
/**
|
||||
* @author Crystal.Sea
|
||||
*
|
||||
*/
|
||||
public class SocialSignOnProvider {
|
||||
|
||||
private String provider;
|
||||
private String providerName;
|
||||
private String icon;
|
||||
private String clientId;
|
||||
private String clientSecret;
|
||||
private String callBack;
|
||||
private String authorizeUrl;
|
||||
private String accessTokenUrl;
|
||||
private String accessTokenMethod;
|
||||
private String scope;
|
||||
private String verifierCode;
|
||||
private String accountUrl;
|
||||
private String accountId;
|
||||
private int sortOrder;
|
||||
|
||||
|
||||
private boolean userBind;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public SocialSignOnProvider() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
public String getProvider() {
|
||||
return provider;
|
||||
}
|
||||
public void setProvider(String provider) {
|
||||
this.provider = provider;
|
||||
}
|
||||
public String getIcon() {
|
||||
return icon;
|
||||
}
|
||||
public void setIcon(String icon) {
|
||||
this.icon = icon;
|
||||
}
|
||||
public String getProviderName() {
|
||||
return providerName;
|
||||
}
|
||||
public void setProviderName(String providerName) {
|
||||
this.providerName = providerName;
|
||||
}
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
public void setClientId(String clientId) {
|
||||
this.clientId = clientId;
|
||||
}
|
||||
public String getClientSecret() {
|
||||
return clientSecret;
|
||||
}
|
||||
public void setClientSecret(String clientSecret) {
|
||||
this.clientSecret = clientSecret;
|
||||
}
|
||||
|
||||
public String getAuthorizeUrl() {
|
||||
return authorizeUrl;
|
||||
}
|
||||
public void setAuthorizeUrl(String authorizeUrl) {
|
||||
this.authorizeUrl = authorizeUrl;
|
||||
}
|
||||
public String getAccessTokenUrl() {
|
||||
return accessTokenUrl;
|
||||
}
|
||||
public void setAccessTokenUrl(String accessTokenUrl) {
|
||||
this.accessTokenUrl = accessTokenUrl;
|
||||
}
|
||||
public String getAccessTokenMethod() {
|
||||
return accessTokenMethod;
|
||||
}
|
||||
public void setAccessTokenMethod(String accessTokenMethod) {
|
||||
this.accessTokenMethod = accessTokenMethod;
|
||||
}
|
||||
public String getScope() {
|
||||
return scope;
|
||||
}
|
||||
public void setScope(String scope) {
|
||||
this.scope = scope;
|
||||
}
|
||||
public String getVerifierCode() {
|
||||
return verifierCode;
|
||||
}
|
||||
public void setVerifierCode(String verifierCode) {
|
||||
this.verifierCode = verifierCode;
|
||||
}
|
||||
public String getAccountUrl() {
|
||||
return accountUrl;
|
||||
}
|
||||
public void setAccountUrl(String accountUrl) {
|
||||
this.accountUrl = accountUrl;
|
||||
}
|
||||
public String getAccountId() {
|
||||
return accountId;
|
||||
}
|
||||
public void setAccountId(String accountId) {
|
||||
this.accountId = accountId;
|
||||
}
|
||||
public int getSortOrder() {
|
||||
return sortOrder;
|
||||
}
|
||||
public void setSortOrder(int sortOrder) {
|
||||
this.sortOrder = sortOrder;
|
||||
}
|
||||
|
||||
public String getCallBack() {
|
||||
return callBack;
|
||||
}
|
||||
|
||||
public void setCallBack(String callBack) {
|
||||
this.callBack = callBack;
|
||||
}
|
||||
|
||||
public boolean isUserBind() {
|
||||
return userBind;
|
||||
}
|
||||
|
||||
public void setUserBind(boolean userBind) {
|
||||
this.userBind = userBind;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SocialSignOnProvider [provider=" + provider + ", providerName="
|
||||
+ providerName + ", icon=" + icon + ", clientId=" + clientId
|
||||
+ ", clientSecret=" + clientSecret + ", authorizeUrl="
|
||||
+ authorizeUrl + ", accessTokenUrl=" + accessTokenUrl
|
||||
+ ", accessTokenMethod=" + accessTokenMethod + ", scope="
|
||||
+ scope + ", verifierCode=" + verifierCode + ", accountUrl="
|
||||
+ accountUrl + ", accountId=" + accountId + ", sortOrder="
|
||||
+ sortOrder + ", userBind=" + userBind + "]";
|
||||
}
|
||||
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
package org.maxkey.authn.support.socialsignon.service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
|
||||
public class SocialSignOnProviderService{
|
||||
private static Logger _logger = LoggerFactory.getLogger(SocialSignOnProviderService.class);
|
||||
|
||||
List<SocialSignOnProvider> socialSignOnProviders;
|
||||
|
||||
HashMap<String ,SocialSignOnProvider>socialSignOnProviderMaps=new HashMap<String ,SocialSignOnProvider>();
|
||||
|
||||
|
||||
public SocialSignOnProvider get(String provider){
|
||||
return socialSignOnProviderMaps.get(provider);
|
||||
}
|
||||
|
||||
public List<SocialSignOnProvider> getSocialSignOnProviders() {
|
||||
return socialSignOnProviders;
|
||||
}
|
||||
|
||||
public void setSocialSignOnProviders(
|
||||
List<SocialSignOnProvider> socialSignOnProviders) {
|
||||
|
||||
this.socialSignOnProviders = socialSignOnProviders;
|
||||
|
||||
for(SocialSignOnProvider socialSignOnProvider : socialSignOnProviders){
|
||||
socialSignOnProviderMaps.put(socialSignOnProvider.getProvider(), socialSignOnProvider);
|
||||
}
|
||||
|
||||
_logger.debug(""+socialSignOnProviders);
|
||||
}
|
||||
|
||||
}
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
package org.maxkey.authn.support.socialsignon.service;
|
||||
|
||||
import org.apache.mybatis.jpa.persistence.JpaBaseDomain;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Crystal.Sea
|
||||
*/
|
||||
public class SocialSignOnUserToken extends JpaBaseDomain {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 2151179554190800162L;
|
||||
private String id;
|
||||
private String provider;
|
||||
private String uid;
|
||||
private String username;
|
||||
private String socialuid;
|
||||
private String socialUserInfo;
|
||||
private String accessToken;
|
||||
private String exAttribute;
|
||||
|
||||
public SocialSignOnUserToken() {}
|
||||
|
||||
/**
|
||||
* @return the id
|
||||
*/
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id the id to set
|
||||
*/
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getProvider() {
|
||||
return provider;
|
||||
}
|
||||
|
||||
public void setProvider(String provider) {
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
public String getUid() {
|
||||
return uid;
|
||||
}
|
||||
|
||||
public void setUid(String uid) {
|
||||
this.uid = uid;
|
||||
}
|
||||
|
||||
public String getSocialuid() {
|
||||
return socialuid;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public void setSocialuid(String socialuid) {
|
||||
this.socialuid = socialuid;
|
||||
}
|
||||
|
||||
public String getSocialUserInfo() {
|
||||
return socialUserInfo;
|
||||
}
|
||||
|
||||
public void setSocialUserInfo(String socialUserInfo) {
|
||||
this.socialUserInfo = socialUserInfo;
|
||||
}
|
||||
|
||||
public String getAccessToken() {
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
public void setAccessToken(String accessToken) {
|
||||
this.accessToken = accessToken;
|
||||
}
|
||||
|
||||
public String getExAttribute() {
|
||||
return exAttribute;
|
||||
}
|
||||
|
||||
public void setExAttribute(String exAttribute) {
|
||||
this.exAttribute = exAttribute;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SocialSignOnUserToken [provider=" + provider + ", uid=" + uid
|
||||
+ ", socialuid=" + socialuid + ", socialUserInfo="
|
||||
+ socialUserInfo + ", accessToken=" + accessToken
|
||||
+ ", exAttribute=" + exAttribute + "]";
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package org.maxkey.authn.support.socialsignon.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public interface SocialSignOnUserTokenService{
|
||||
|
||||
public boolean insert(SocialSignOnUserToken socialSignOnUserToken);
|
||||
|
||||
public List<SocialSignOnUserToken> query (SocialSignOnUserToken socialSignOnUserToken);
|
||||
|
||||
public SocialSignOnUserToken get (SocialSignOnUserToken socialSignOnUserToken);
|
||||
|
||||
public boolean delete (SocialSignOnUserToken socialSignOnUserToken);
|
||||
|
||||
public boolean update (SocialSignOnUserToken socialSignOnUserToken);
|
||||
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
package org.maxkey.authn.support.wsfederation;
|
||||
|
||||
import java.util.Map;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
/**
|
||||
* This will remove the @example.org from the upn local accounts. Other IdP should
|
||||
* have the upn un-altered to prevent users collusions in CAS-based applications.
|
||||
*
|
||||
*/
|
||||
public class WsFedAttributeMutatorImpl implements WsFederationAttributeMutator {
|
||||
private static final Logger _logger = LoggerFactory.getLogger(WsFedAttributeMutatorImpl.class);
|
||||
|
||||
@Override
|
||||
public void modifyAttributes(Map<String, Object> attributes,String upnSuffix) {
|
||||
if ( attributes.containsKey("upn") ) {
|
||||
attributes.put("upn", attributes.get("upn").toString().replace("@"+upnSuffix, ""));
|
||||
_logger.debug(String.format("modifyAttributes: upn modified (%s)", attributes.get("upn").toString()));
|
||||
}else {
|
||||
_logger.warn("modifyAttributes: upn attribute not found");
|
||||
}
|
||||
|
||||
attributeMapping(attributes, "surname", "LastName");
|
||||
attributeMapping(attributes, "givenname", "FirstName");
|
||||
attributeMapping(attributes, "Group", "Groups");
|
||||
attributeMapping(attributes, "employeeNumber", "UDC_IDENTIFIER");
|
||||
}
|
||||
|
||||
private void attributeMapping(Map<String, Object> attributes, String oldName, String newName) {
|
||||
if ( attributes.containsKey(oldName) ) {
|
||||
_logger.debug(String.format("attributeRemapping: %s -> %s (%s)", oldName, newName, attributes.get(oldName)));
|
||||
attributes.put(newName, attributes.get(oldName));
|
||||
attributes.remove(oldName);
|
||||
} else {
|
||||
_logger.debug(String.format("attributeRemapping: attribute not found (%s)", oldName));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
|
||||
package org.maxkey.authn.support.wsfederation;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* This interface provides a mechanism to alter the SAML attributes before they
|
||||
* are added the WsFederationCredentials and returned to Sec
|
||||
*/
|
||||
public interface WsFederationAttributeMutator {
|
||||
/**
|
||||
* modifyAttributes manipulates the attributes before they are assigned to the credential.
|
||||
*
|
||||
* @param attributes the attribute returned by the IdP.
|
||||
*/
|
||||
void modifyAttributes(Map<String, Object> attributes,String upnSuffix);
|
||||
}
|
||||
+159
@@ -0,0 +1,159 @@
|
||||
|
||||
package org.maxkey.authn.support.wsfederation;
|
||||
|
||||
import org.opensaml.xml.security.x509.BasicX509Credential;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This class gathers configuration information for the WS Federation Identity Provider.
|
||||
*
|
||||
*/
|
||||
public final class WsFederationConfiguration {
|
||||
|
||||
@NotNull
|
||||
private String identifier;
|
||||
|
||||
@NotNull
|
||||
private String url;
|
||||
|
||||
@NotNull
|
||||
private String principal;
|
||||
|
||||
@NotNull
|
||||
private String relyingParty;
|
||||
|
||||
private String upnSuffix;
|
||||
@NotNull
|
||||
private List<Resource> signingCertificates;
|
||||
|
||||
private int tolerance = 10000;
|
||||
|
||||
private List<BasicX509Credential> signingWallet;
|
||||
|
||||
private WsFederationAttributeMutator attributeMutator;
|
||||
|
||||
private String logoutUrl;
|
||||
|
||||
public String getIdentifier() {
|
||||
return identifier;
|
||||
}
|
||||
|
||||
public void setIdentifier(String identifier) {
|
||||
this.identifier = identifier;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getPrincipal() {
|
||||
return principal;
|
||||
}
|
||||
|
||||
public void setPrincipal(String principal) {
|
||||
this.principal = principal;
|
||||
}
|
||||
|
||||
public String getRelyingParty() {
|
||||
return relyingParty;
|
||||
}
|
||||
|
||||
public void setRelyingParty(String relyingParty) {
|
||||
this.relyingParty = relyingParty;
|
||||
}
|
||||
|
||||
public List<BasicX509Credential> getSigningWallet() {
|
||||
return signingWallet;
|
||||
}
|
||||
|
||||
public void setSigningWallet(List<BasicX509Credential> signingWallet) {
|
||||
this.signingWallet = signingWallet;
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the signing certificates.
|
||||
*
|
||||
* @return X509credentials of the signing certs
|
||||
*/
|
||||
public List<BasicX509Credential> getSigningCertificates() {
|
||||
return this.signingWallet;
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the signing certs.
|
||||
*
|
||||
* @param signingCertificateFiles a list of certificate files to read in.
|
||||
*/
|
||||
public void setSigningCertificates(final List<Resource> signingCertificateFiles) {
|
||||
this.signingCertificates = signingCertificateFiles;
|
||||
|
||||
final List<BasicX509Credential> signingCerts = new ArrayList<BasicX509Credential>();
|
||||
|
||||
for (Resource file : signingCertificateFiles) {
|
||||
signingCerts.add(WsFederationUtils.getSigningCredential(file));
|
||||
}
|
||||
|
||||
this.signingWallet = signingCerts;
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the tolerance.
|
||||
*
|
||||
* @return the tolerance in milliseconds
|
||||
*/
|
||||
public int getTolerance() {
|
||||
return tolerance;
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the tolerance of the validity of the timestamp token.
|
||||
*
|
||||
* @param tolerance the tolerance in milliseconds
|
||||
*/
|
||||
public void setTolerance(final int tolerance) {
|
||||
this.tolerance = tolerance;
|
||||
}
|
||||
|
||||
/**
|
||||
* gets the attributeMutator.
|
||||
*
|
||||
* @return an attributeMutator
|
||||
*/
|
||||
public WsFederationAttributeMutator getAttributeMutator() {
|
||||
return attributeMutator;
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the attributeMutator.
|
||||
*
|
||||
* @param attributeMutator an attributeMutator
|
||||
*/
|
||||
public void setAttributeMutator(final WsFederationAttributeMutator attributeMutator) {
|
||||
this.attributeMutator = attributeMutator;
|
||||
}
|
||||
|
||||
public String getUpnSuffix() {
|
||||
return upnSuffix;
|
||||
}
|
||||
|
||||
public void setUpnSuffix(String upnSuffix) {
|
||||
this.upnSuffix = upnSuffix;
|
||||
}
|
||||
|
||||
public String getLogoutUrl() {
|
||||
return logoutUrl;
|
||||
}
|
||||
|
||||
public void setLogoutUrl(String logoutUrl) {
|
||||
this.logoutUrl = logoutUrl;
|
||||
}
|
||||
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package org.maxkey.authn.support.wsfederation;
|
||||
|
||||
public class WsFederationConstants {
|
||||
public static final String LOCALE = "locale";
|
||||
public static final String METHOD = "method";
|
||||
public static final String PROVIDERURL = "WsFederationIdentityProviderUrl";
|
||||
public static final String QUERYSTRING = "?wa=wsignin1.0&wtrealm=";
|
||||
public static final String SERVICE = "service";
|
||||
public static final String THEME = "theme";
|
||||
public static final String WA = "wa";
|
||||
public static final String WCTX = "wctx";
|
||||
public static final String WRESULT = "wresult";
|
||||
public static final String WSIGNIN = "wsignin1.0";
|
||||
}
|
||||
+152
@@ -0,0 +1,152 @@
|
||||
|
||||
package org.maxkey.authn.support.wsfederation;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* This class represents the basic elements of the WsFederation token.
|
||||
*
|
||||
*/
|
||||
public final class WsFederationCredential {
|
||||
private final Logger _logger = LoggerFactory.getLogger(WsFederationCredential.class);
|
||||
|
||||
private String audience;
|
||||
private String authenticationMethod;
|
||||
private String id;
|
||||
private String issuer;
|
||||
private DateTime issuedOn;
|
||||
private DateTime notBefore;
|
||||
private DateTime notOnOrAfter;
|
||||
private DateTime retrievedOn;
|
||||
private Map<String, Object> attributes;
|
||||
|
||||
public String getAuthenticationMethod() {
|
||||
return this.authenticationMethod;
|
||||
}
|
||||
|
||||
public void setAuthenticationMethod(final String authenticationMethod) {
|
||||
this.authenticationMethod = authenticationMethod;
|
||||
}
|
||||
|
||||
public String getAudience() {
|
||||
return this.audience;
|
||||
}
|
||||
|
||||
public void setAudience(final String audience) {
|
||||
this.audience = audience;
|
||||
}
|
||||
|
||||
public Map<String, Object> getAttributes() {
|
||||
return this.attributes;
|
||||
}
|
||||
|
||||
public void setAttributes(final Map<String, Object> attributes) {
|
||||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public void setId(final String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public DateTime getIssuedOn() {
|
||||
return this.issuedOn;
|
||||
}
|
||||
|
||||
public void setIssuedOn(final DateTime issuedOn) {
|
||||
this.issuedOn = issuedOn;
|
||||
}
|
||||
|
||||
public String getIssuer() {
|
||||
return this.issuer;
|
||||
}
|
||||
|
||||
public void setIssuer(final String issuer) {
|
||||
this.issuer = issuer;
|
||||
}
|
||||
|
||||
public DateTime getNotBefore() {
|
||||
return this.notBefore;
|
||||
}
|
||||
|
||||
public void setNotBefore(final DateTime notBefore) {
|
||||
this.notBefore = notBefore;
|
||||
}
|
||||
|
||||
public DateTime getNotOnOrAfter() {
|
||||
return this.notOnOrAfter;
|
||||
}
|
||||
|
||||
public void setNotOnOrAfter(final DateTime notOnOrAfter) {
|
||||
this.notOnOrAfter = notOnOrAfter;
|
||||
}
|
||||
|
||||
public DateTime getRetrievedOn() {
|
||||
return this.retrievedOn;
|
||||
}
|
||||
|
||||
public void setRetrievedOn(final DateTime retrievedOn) {
|
||||
this.retrievedOn = retrievedOn;
|
||||
}
|
||||
|
||||
/**
|
||||
* toString produces a human readable representation of the WsFederationCredential.
|
||||
*
|
||||
* @return a human readable representation of the WsFederationCredential
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
String attributeList = "";
|
||||
|
||||
for (String attr : this.attributes.keySet()) {
|
||||
attributeList += " " + attr + ": " + (attributes.get(attr)).toString() + "\n";
|
||||
}
|
||||
|
||||
final String readable = "ID: %s\nIssuer: %s\nAudience: %s\nAudience Method: %s\nIssued On: %s\n"
|
||||
+ "Valid After: %s\nValid Before: %s\nAttributes:\n%s";
|
||||
|
||||
return String.format(readable, this.id, this.issuer, this.audience, this.authenticationMethod,
|
||||
this.issuedOn.toString(), this.notBefore.toString(), this.notOnOrAfter.toString(), attributeList);
|
||||
}
|
||||
|
||||
/**
|
||||
* isValid validates the credential.
|
||||
*
|
||||
* @param expectedAudience the audience that the token was issued to (CAS Server)
|
||||
* @param expectedIssuer the issuer of the token (the IdP)
|
||||
* @param timeDrift the amount of acceptable time drift
|
||||
* @return true if the credentials are valid, otherwise false
|
||||
*/
|
||||
public boolean isValid(final String expectedAudience, final String expectedIssuer, final int timeDrift) {
|
||||
if (!this.getAudience().equalsIgnoreCase(expectedAudience)) {
|
||||
_logger.warn(".isValid: audience is invalid: {}", this.getAudience());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.getIssuer().equalsIgnoreCase(expectedIssuer)) {
|
||||
_logger.warn(".isValid: issuer is invalid: {}", this.getIssuer());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.getIssuedOn().isBefore(this.getRetrievedOn().minusMillis(timeDrift))
|
||||
|| this.getIssuedOn().isAfter(this.getRetrievedOn().plusMillis(timeDrift))) {
|
||||
_logger.warn(".isValid: Ticket outside of drift.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.getRetrievedOn().isAfter(this.getNotOnOrAfter())) {
|
||||
_logger.warn(".isValid: ticket is too late.");
|
||||
return false;
|
||||
}
|
||||
|
||||
_logger.debug(".isValid: credential is valid.");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package org.maxkey.authn.support.wsfederation;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
public interface WsFederationService {
|
||||
public boolean login(String wsFederationWA,String wsFederationWResult,HttpServletRequest request);
|
||||
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
package org.maxkey.authn.support.wsfederation;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.maxkey.constants.LOGINTYPE;
|
||||
import org.maxkey.util.StringUtils;
|
||||
import org.maxkey.web.WebContext;
|
||||
import org.opensaml.saml1.core.impl.AssertionImpl;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
||||
public class WsFederationServiceImpl implements WsFederationService{
|
||||
final static Logger _logger = LoggerFactory.getLogger(WsFederationServiceImpl.class);
|
||||
|
||||
private WsFederationConfiguration wsFederationConfiguration;
|
||||
|
||||
public boolean login(String wsFederationWA,String wsFederationWResult,HttpServletRequest request){
|
||||
// it's an authentication
|
||||
if (StringUtils.isNotEmpty(wsFederationWA) && wsFederationWA.equalsIgnoreCase(WsFederationConstants.WSIGNIN)) {
|
||||
_logger.debug("wresult : {}"+wsFederationWResult);
|
||||
|
||||
final String wctx = request.getParameter(WsFederationConstants.WCTX);
|
||||
_logger.debug("wctx : {}"+ wctx);
|
||||
|
||||
// create credentials
|
||||
final AssertionImpl assertion = WsFederationUtils.parseTokenFromString(wsFederationWResult);
|
||||
//Validate the signature
|
||||
if (assertion != null && WsFederationUtils.validateSignature(assertion, wsFederationConfiguration.getSigningCertificates())) {
|
||||
final WsFederationCredential wsFederationCredential = WsFederationUtils.createCredentialFromToken(assertion);
|
||||
|
||||
if (wsFederationCredential != null && wsFederationCredential.isValid(wsFederationConfiguration.getRelyingParty(),
|
||||
wsFederationConfiguration.getIdentifier(),
|
||||
wsFederationConfiguration.getTolerance())) {
|
||||
|
||||
//Give the library user a chance to change the attributes as necessary
|
||||
if (wsFederationConfiguration.getAttributeMutator() != null) {
|
||||
wsFederationConfiguration.getAttributeMutator().modifyAttributes(
|
||||
wsFederationCredential.getAttributes(),
|
||||
wsFederationConfiguration.getUpnSuffix());
|
||||
}
|
||||
|
||||
return WebContext.setAuthentication(
|
||||
wsFederationCredential.getAttributes().get("").toString(),
|
||||
LOGINTYPE.WSFEDERATION,
|
||||
"","","success");
|
||||
|
||||
} else {
|
||||
_logger.warn("SAML assertions are blank or no longer valid.");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
_logger.error("WS Requested Security Token is blank or the signature is not valid.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setWsFederationConfiguration(
|
||||
WsFederationConfiguration wsFederationConfiguration) {
|
||||
this.wsFederationConfiguration = wsFederationConfiguration;
|
||||
}
|
||||
|
||||
}
|
||||
+269
@@ -0,0 +1,269 @@
|
||||
|
||||
package org.maxkey.authn.support.wsfederation;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.DateTimeZone;
|
||||
import org.opensaml.DefaultBootstrap;
|
||||
import org.opensaml.saml1.core.Attribute;
|
||||
import org.opensaml.saml1.core.Conditions;
|
||||
import org.opensaml.saml1.core.impl.AssertionImpl;
|
||||
import org.opensaml.ws.wsfed.RequestedSecurityToken;
|
||||
import org.opensaml.ws.wsfed.impl.RequestSecurityTokenResponseImpl;
|
||||
import org.opensaml.xml.Configuration;
|
||||
import org.opensaml.xml.ConfigurationException;
|
||||
import org.opensaml.xml.io.Unmarshaller;
|
||||
import org.opensaml.xml.io.UnmarshallerFactory;
|
||||
import org.opensaml.xml.io.UnmarshallingException;
|
||||
import org.opensaml.xml.parse.BasicParserPool;
|
||||
import org.opensaml.xml.parse.XMLParserException;
|
||||
import org.opensaml.xml.schema.XSAny;
|
||||
import org.opensaml.xml.security.x509.BasicX509Credential;
|
||||
import org.opensaml.xml.signature.Signature;
|
||||
import org.opensaml.xml.signature.SignatureValidator;
|
||||
import org.opensaml.xml.validation.ValidationException;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PublicKey;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Helper class that does the heavy lifting with the openSaml library.
|
||||
*
|
||||
*/
|
||||
public final class WsFederationUtils {
|
||||
/**
|
||||
* Initialized the openSaml library.
|
||||
*/
|
||||
static {
|
||||
final Logger _logger = LoggerFactory.getLogger(WsFederationUtils.class);
|
||||
|
||||
try {
|
||||
// Initialize the library
|
||||
DefaultBootstrap.bootstrap();
|
||||
} catch (final ConfigurationException ex) {
|
||||
_logger.error(ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* private constructor.
|
||||
*/
|
||||
private WsFederationUtils() {
|
||||
}
|
||||
|
||||
/**
|
||||
* createCredentialFromToken converts a SAML 1.1 assertion to a WSFederationCredential.
|
||||
*
|
||||
* @param assertion the provided assertion
|
||||
* @return an equivalent credential.
|
||||
*/
|
||||
public static WsFederationCredential createCredentialFromToken(final AssertionImpl assertion) {
|
||||
final Logger _logger = LoggerFactory.getLogger(WsFederationUtils.class);
|
||||
|
||||
final DateTime retrievedOn = new DateTime().withZone(DateTimeZone.UTC);
|
||||
_logger.debug("createCredentialFromToken: retrieved on {}", retrievedOn.toString());
|
||||
|
||||
final WsFederationCredential credential = new WsFederationCredential();
|
||||
credential.setRetrievedOn(retrievedOn);
|
||||
credential.setId(assertion.getID());
|
||||
credential.setIssuer(assertion.getIssuer());
|
||||
credential.setIssuedOn(assertion.getIssueInstant());
|
||||
|
||||
final Conditions conditions = assertion.getConditions();
|
||||
if (conditions != null) {
|
||||
credential.setNotBefore(conditions.getNotBefore());
|
||||
credential.setNotOnOrAfter(conditions.getNotOnOrAfter());
|
||||
credential.setAudience(conditions.getAudienceRestrictionConditions().get(0).getAudiences().get(0).getUri());
|
||||
}
|
||||
|
||||
if (assertion.getAuthenticationStatements() != null && assertion.getAuthenticationStatements().size() > 0) {
|
||||
credential.setAuthenticationMethod(assertion.getAuthenticationStatements().get(0).getAuthenticationMethod());
|
||||
}
|
||||
|
||||
//retrieve an attributes from the assertion
|
||||
final HashMap<String, Object> attributes = new HashMap<String, Object>();
|
||||
for (Attribute item : assertion.getAttributeStatements().get(0).getAttributes()) {
|
||||
_logger.debug("createCredentialFromToken: processed attribute: {}", item.getAttributeName());
|
||||
|
||||
if (item.getAttributeValues().size() == 1) {
|
||||
attributes.put(item.getAttributeName(), ((XSAny) item.getAttributeValues().get(0)).getTextContent());
|
||||
|
||||
} else {
|
||||
|
||||
final ArrayList<String> itemList = new ArrayList<String>();
|
||||
|
||||
for (int i = 0; i < item.getAttributeValues().size(); i++) {
|
||||
itemList.add(((XSAny) item.getAttributeValues().get(i)).getTextContent());
|
||||
}
|
||||
|
||||
if (!itemList.isEmpty()) {
|
||||
attributes.put(item.getAttributeName(), itemList);
|
||||
}
|
||||
}
|
||||
}
|
||||
credential.setAttributes(attributes);
|
||||
|
||||
_logger.debug("createCredentialFromToken: {}", credential.toString());
|
||||
|
||||
return credential;
|
||||
}
|
||||
|
||||
/**
|
||||
* getSigningCredential loads up an X509Credential from a file.
|
||||
*
|
||||
* @param resource the signing certificate file
|
||||
* @return an X509 credential
|
||||
*/
|
||||
public static BasicX509Credential getSigningCredential(final Resource resource) {
|
||||
final Logger _logger = LoggerFactory.getLogger(WsFederationUtils.class);
|
||||
|
||||
BasicX509Credential publicCredential;
|
||||
|
||||
try {
|
||||
//grab the certificate file
|
||||
final InputStream inputStream = resource.getInputStream();
|
||||
final CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
|
||||
final X509Certificate certificate = (X509Certificate) certificateFactory.generateCertificate(inputStream);
|
||||
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (final IOException ex) {
|
||||
_logger.warn("Error closing the signing cert file: {}", ex.getMessage());
|
||||
}
|
||||
|
||||
//get the public key from the certificate
|
||||
final X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(certificate.getPublicKey().getEncoded());
|
||||
|
||||
//generate public key to validate signatures
|
||||
final KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||
final PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
|
||||
|
||||
//add the public key
|
||||
publicCredential = new BasicX509Credential();
|
||||
publicCredential.setPublicKey(publicKey);
|
||||
|
||||
} catch (final CertificateException ex) {
|
||||
_logger.error("Error retrieving the signing cert: {}", ex.getMessage());
|
||||
return null;
|
||||
|
||||
} catch (final InvalidKeySpecException ex) {
|
||||
_logger.error("Error retrieving the signing cert: {}", ex.getMessage());
|
||||
return null;
|
||||
|
||||
} catch (final NoSuchAlgorithmException ex) {
|
||||
_logger.error("Error retrieving the signing cert: {}", ex.getMessage());
|
||||
return null;
|
||||
|
||||
} catch (final IOException ex) {
|
||||
_logger.error("Error retrieving the signing cert: " + ex.getMessage());
|
||||
return null;
|
||||
}
|
||||
|
||||
_logger.debug("getSigningCredential: key retrieved.");
|
||||
return publicCredential;
|
||||
}
|
||||
|
||||
/**
|
||||
* parseTokenFromString converts a raw wresult and extracts it into an assertion.
|
||||
*
|
||||
* @param wresult the raw token returned by the IdP
|
||||
* @return an assertion
|
||||
*/
|
||||
public static AssertionImpl parseTokenFromString(final String wresult) {
|
||||
final Logger _logger = LoggerFactory.getLogger(WsFederationUtils.class);
|
||||
|
||||
RequestSecurityTokenResponseImpl rsToken;
|
||||
|
||||
final BasicParserPool parserPool = new BasicParserPool();
|
||||
parserPool.setNamespaceAware(true);
|
||||
|
||||
try {
|
||||
final InputStream in = new ByteArrayInputStream(wresult.getBytes("UTF-8"));
|
||||
final Document document = parserPool.parse(in);
|
||||
final Element metadataRoot = document.getDocumentElement();
|
||||
final UnmarshallerFactory unmarshallerFactory = Configuration.getUnmarshallerFactory();
|
||||
final Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(metadataRoot);
|
||||
rsToken = (RequestSecurityTokenResponseImpl) unmarshaller.unmarshall(metadataRoot);
|
||||
|
||||
} catch (final UnmarshallingException ex) {
|
||||
_logger.warn(ex.getMessage());
|
||||
return null;
|
||||
|
||||
} catch (final XMLParserException ex) {
|
||||
_logger.warn(ex.getMessage());
|
||||
return null;
|
||||
|
||||
} catch (final UnsupportedEncodingException ex) {
|
||||
_logger.warn(ex.getMessage());
|
||||
return null;
|
||||
}
|
||||
|
||||
//Get our SAML token
|
||||
final List<RequestedSecurityToken> rst = rsToken.getRequestedSecurityToken();
|
||||
final AssertionImpl assertion = (AssertionImpl) rst.get(0).getSecurityTokens().get(0);
|
||||
|
||||
if (assertion == null) {
|
||||
_logger.debug("parseTokenFromString: assertion null");
|
||||
} else {
|
||||
_logger.debug("parseTokenFromString: {}", assertion.toString());
|
||||
}
|
||||
|
||||
return assertion;
|
||||
}
|
||||
|
||||
/**
|
||||
* validateSignature checks to see if the signature on an assertion is valid.
|
||||
*
|
||||
* @param assertion a provided assertion
|
||||
* @param x509Creds list of x509certs to check.
|
||||
* @return true if the assertion's signature is valid, otherwise false
|
||||
*/
|
||||
public static boolean validateSignature(final AssertionImpl assertion, final List<BasicX509Credential> x509Creds) {
|
||||
final Logger _logger = LoggerFactory.getLogger(WsFederationUtils.class);
|
||||
|
||||
SignatureValidator signatureValidator;
|
||||
|
||||
for (BasicX509Credential cred : x509Creds) {
|
||||
try {
|
||||
signatureValidator = new SignatureValidator(cred);
|
||||
} catch (final Exception ex) {
|
||||
_logger.warn(ex.getMessage());
|
||||
break;
|
||||
}
|
||||
|
||||
//get the signature to validate from the response object
|
||||
final Signature signature = assertion.getSignature();
|
||||
|
||||
//try to validate
|
||||
try {
|
||||
signatureValidator.validate(signature);
|
||||
_logger.debug("validateSignature: Signature is valid.");
|
||||
return true;
|
||||
|
||||
} catch (final ValidationException ex) {
|
||||
_logger.warn("validateSignature: Signature is NOT valid.");
|
||||
_logger.warn(ex.getMessage());
|
||||
}
|
||||
}
|
||||
_logger.warn("validateSignature: Signature doesn't match any signing credential.");
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* @author Administrator
|
||||
*
|
||||
*/
|
||||
package org.maxkey;
|
||||
Reference in New Issue
Block a user