Commit 3484642a authored by Bruno Nocera Zanette's avatar Bruno Nocera Zanette

Modified AuthMethod to use Kerberos/LDAP

Project was modified to use Kerberos as the Login Method and LDAP as the authorities source.

Properties files were created to store information about Kerberos and LDAP servers (kerberos.properties and ldap.properties), and the groups that define each authority group into SAPos (authorities.properties).

To control LDAP attributes the class "LdapAttrController" was created. Into this class all necessary LDAP's attributes are aquired and repassed to the class "KerberosAuthController" that uses this information to create a new instance of "User" that is used on login process.

The libraries "spring-ldap-core" and "spring-security-kerberos-core" were added into "pom.xml" file.
Signed-off-by: Bruno Nocera Zanette's avatarBruno Nocera Zanette <brunonzanette@gmail.com>
parent c242bf1e
......@@ -44,6 +44,13 @@
<name>Spring Roo Repository</name>
<url>http://spring-roo-repository.springsource.org/release</url>
</repository>
<repository>
<id>springsource-milestones</id>
<name>SpringSource Milestones Proxy</name>
<url>https://oss.sonatype.org/content/repositories/springsource-milestones</url>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
......@@ -82,12 +89,34 @@
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.1.3</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.0.4</version>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>3.1.0.GA</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcmail-jdk14</artifactId>
<version>1.38</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk14</artifactId>
<version>1.38</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bctsp-jdk14</artifactId>
<version>1.38</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
......@@ -444,6 +473,19 @@
<artifactId>spring-security-taglibs</artifactId>
<version>${spring-security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.ldap</groupId>
<artifactId>spring-ldap-core</artifactId>
<version>1.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security.extensions</groupId>
<artifactId>spring-security-kerberos-core</artifactId>
<version>1.0.0.M2</version>
</dependency>
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
......
package br.ufpr.c3sl.sapos.web;
import br.ufpr.c3sl.sapos.web.LdapAttrController;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
// This class was implemented based on the following tutorials:
// * https://github.com/spring-projects/spring-security-kerberos
public class KerberosAuthController implements UserDetailsService {
// Get the lists of LDAP groups that defines each authority group
// from "authorities.properties" file.
@Value("#{'${authorities.administrador}'.split(',')}")
private List<?> authListAdministrador;
@Value("#{'${authorities.funcionario}'.split(',')}")
private List<?> authListFuncionario;
@Value("#{'${authorities.professor}'.split(',')}")
private List<?> authListProfessor;
@Value("#{'${authorities.aluno}'.split(',')}")
private List<?> authListAluno;
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException, DataAccessException {
// Get user's LDAP groups.
// The split method is used because the username is formatted in
// Kerbero's default: "username@C3LOCAL" (krbPrincipalName)
List<?> personGroups = LdapAttrController
.getPersonGroups(username.split("@")[0]);
// Initialize an array to store the user's authorities list
List<String> personAuthorities = new ArrayList<String>();
// Compares all user groups against pre-determined Authorities groups
// and builds a list of user's authorities.
Iterator<?> itr = personGroups.iterator();
while (itr.hasNext()) {
Object group = itr.next();
if (authListAdministrador.contains(group)) {
personAuthorities.add("Administrador");
}
if (authListFuncionario.contains(group)) {
personAuthorities.add("Funcionario");
}
if (authListProfessor.contains(group)) {
personAuthorities.add("Professor");
}
if (authListAluno.contains(group)) {
personAuthorities.add("Aluno");
}
}
// If user's authorities list is empty, returns "No Permission"
// exception
if (personAuthorities.isEmpty())
throw new UsernameNotFoundException("Acesso negado");
// Returns a new instance of User, containing user security details
return new User(username,"notUsed",true,true,true,true,
AuthorityUtils.createAuthorityList(personAuthorities.toString()));
}
}
\ No newline at end of file
package br.ufpr.c3sl.sapos.web;
import java.util.List;
import org.springframework.ldap.core.AttributesMapper;
import org.springframework.ldap.core.LdapTemplate;
// This class was implemented based on the following tutorials:
// * http://docs.spring.io/spring-ldap/docs/1.3.x/reference/html/introduction.html
// * http://www.programcreek.com/2009/08/how-to-connect-ldap-server-using-spring-ldap-framework/
public class LdapAttrController {
private static LdapTemplate ldapTemplate;
public void setLdapTemplate(LdapTemplate ldapTemplate) {
LdapAttrController.ldapTemplate = ldapTemplate;
}
private static AttributesMapper getLdapAttr(final String fieldName) {
return new AttributesMapper() {
@Override
public Object mapFromAttributes(
javax.naming.directory.Attributes arg0)
throws javax.naming.NamingException {
return arg0.get(fieldName).get();
}
};
}
public static List<?> getPersonGroups(String username) {
// Implements the following ldapsearch:
// ldapsearch -x -h HOST -p 389 -b BASE "memberUid=username" cn
// Where:
// -x Because it is an anonymous search (no need for an admin user)
// -h/HOST, -p/PORT and -b/BASE are defined at ldap.properties
// The filter is defined by ("memberUid=" + username),
// and getLdapAttr method returns only "cn" field
return ldapTemplate.search("", "memberUid=" + username,
getLdapAttr("cn"));
}
}
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">
<!-- HTTP security configurations -->
<http auto-config="true" use-expressions="true">
......@@ -76,31 +74,13 @@
<intercept-url pattern="/registrationrequests/**" access="permitAll" />
<intercept-url pattern="/registrationrequests**/**" access="permitAll" />
<intercept-url pattern="/**" access="isAuthenticated()" />
</http>
<!-- Configure Authentication mechanism -->
<authentication-manager alias="authenticationManager">
<!-- SHA-256 values can be produced using 'echo -n your_desired_password | sha256sum' (using normal *nix environments) -->
<authentication-provider>
<jdbc-user-service
data-source-ref="dataSource"
users-by-username-query="SELECT user_name, password, 't' FROM person WHERE user_name=?"
authorities-by-username-query="SELECT user_name, user_kind FROM person WHERE user_name=? " />
<password-encoder hash="sha-256"/>
<!-- <user-service> -->
<!-- password="edc2feedd895bd72f6aed5df35197073090e4b0e41b1c525de7635674ac9c6ea" prod -->
<!-- <user name="devel" password="c590eb19109a5d23edd3807625ce51be71bdc2cbe4885a2ef39afb8cdc4d1724" authorities="Administrador"/> -->
<!-- </user-service> -->
</authentication-provider>
<!-- Defines Kerberos as the authentication method -->
<authentication-manager alias="authenticationManager">
<authentication-provider ref="kerberosAuthenticationProvider" />
</authentication-manager>
</beans:beans>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<!--
This will automatically locate any and all property files you have
within your classpath, provided they fall under the META-INF/spring
......@@ -61,19 +71,52 @@
<property name="dataSource" ref="dataSource"/>
</bean>
<context:annotation-config/>
<bean class="org.springframework.mail.javamail.JavaMailSenderImpl" id="mailSender">
<property name="host" value="${email.host}"/>
<property name="protocol" value="${email.protocol}"/>
<property name="port" value="${email.port}"/>
<property name="username" value="${email.username}"/>
<property name="password" value="${email.password}"/>
<property name="javaMailProperties">
<props>
<prop key="mail.smtp.auth">true</prop>
<prop key="mail.smtp.starttls.enable">true</prop>
</props>
</property>
</bean>
</beans>
<bean class="org.springframework.mail.javamail.JavaMailSenderImpl"
id="mailSender">
<property name="host" value="${email.host}" />
<property name="protocol" value="${email.protocol}" />
<property name="port" value="${email.port}" />
<property name="username" value="${email.username}" />
<property name="password" value="${email.password}" />
<property name="javaMailProperties">
<props>
<prop key="mail.smtp.auth">true</prop>
<prop key="mail.smtp.starttls.enable">true</prop>
</props>
</property>
</bean>
<!-- These beans configure LDAP as the User's attributes server-->
<bean id="ldapContextSource" class="org.springframework.ldap.core.support.LdapContextSource">
<property name="url" value="${ldap.server}" />
<property name="base" value="${ldap.base}" />
</bean>
<bean id="ldapTemplate" class="org.springframework.ldap.core.LdapTemplate">
<constructor-arg ref="ldapContextSource" />
</bean>
<bean id="ldapAttrController" class="br.ufpr.c3sl.sapos.web.LdapAttrController">
<property name="ldapTemplate" ref="ldapTemplate" />
</bean>
<!-- These beans configure Kerberos as the Authentication method -->
<bean id="kerberosAuthenticationProvider"
class="org.springframework.security.extensions.kerberos.KerberosAuthenticationProvider">
<property name="kerberosClient">
<bean
class="org.springframework.security.extensions.kerberos.SunJaasKerberosClient">
<property name="debug" value="${krb.debug}" />
</bean>
</property>
<property name="userDetailsService" ref="MyUserDetailsService" />
</bean>
<bean
class="org.springframework.security.extensions.kerberos.GlobalSunJaasKerberosConfig">
<property name="debug" value="${krb.debug}" />
<property name="krbConfLocation" value="${krb.conf.location}" />
</bean>
<bean id="MyUserDetailsService" class="br.ufpr.c3sl.sapos.web.KerberosAuthController" />
</beans>
\ No newline at end of file
# Defines Authorities groups based on LDAP Groups
# Each authority group can have more than one LDAP group,
# separated by a comma (",").
authorities.administrador=pos
authorities.funcionario=func
authorities.professor=prof
authorities.aluno=ppginf,bcc
\ No newline at end of file
# These settings are always needed
# ================================
krb.debug=true
# These settings are only needed for SPNEGO Authentication
# ========================================================
#krb.service.prinicipal=HTTP/web.springsource.com
# Setting keyTabLocation to a classpath resource will most likely not work in a Java EE application Server
# See the Javadoc of SunJaasKerberosTicketValidator for more information on that
#krb.keytab.location=file:/etc/web-springsource-com.keytab
# These settings are only needed for server side Kerberos Authentication
# ======================================================================
# No Prefix is supported in krb.conf.location. It must always be an absolute path.
krb.conf.location=/etc/krb5.conf
# This setting reproduces the following ldapsearch configuration:
# ldapsearch -x -h ldap://urquell -p 389 -b "dc=c3local"
# Defines LDAP Server:
ldap.server=ldap://urquell:389
# Defines LDAP Base:
ldap.base=dc=c3local
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment