Domanda

I managed to get my application working with Active Directory (basically LDAP) using spring-security, like this:

<authentication-manager>
    <authentication-provider ref="ldapActiveDirectoryAuthProvider" />
</authentication-manager>

<beans:bean id="grantedAuthoritiesMapper" class="mypackage.ActiveDirectoryGrantedAuthoritiesMapper"/>
    <beans:bean id="ldapActiveDirectoryAuthProvider" class="org.springframework.security.ldap.authentication.ad.ActiveDirectoryLdapAuthenticationProvider">
    <beans:constructor-arg value="xxxx.xxx.xxxx" />
    <beans:constructor-arg value="ldap://xxx.xxx.xxx.xxx:389" /> 
    <beans:property name="authoritiesMapper" ref="grantedAuthoritiesMapper" />
    <beans:property name="useAuthenticationRequestCredentials" value="true" />
    <beans:property name="convertSubErrorCodesToExceptions" value="true" />
</beans:bean> 

But by doing only this I need to have the users registered both in my application and in the Active Directory before-hand. I would like to be able to before the user logs in (but after the Active Directory validation) to see if he exists in my database and if he doesn't create a new user in my application and then proceed as normal.

I believe I need to create a preAuthentication provider, but I don't know exactly where I can insert my own class to code the checking and registration of the user.

Optimally I would also like to check for a specific authority before creating the user.

Can anyone give me a hand?

È stato utile?

Soluzione

In the end I had to change my authentication handler onAuthenticationSuccess. In spring there are authentication and login in the lifecycle of the login process. During authentication the user is, well, authenticated, but not yet logged into the application (ie only its credentials were deemed valid, but the rest of the application is not aware of the user yet.)

I changed my security.xml to:

<beans:bean id="authHandler" class="mypackage.activedirectory.ActiveDirectoryAuthenticationHandler" 

...

<form-login login-page="/login" authentication-failure-handler-ref="authHandler"
            authentication-success-handler-ref="authHandler" />

And here is the class:

public class ActiveDirectoryAuthenticationHandler extends MyAuthenticationHandler {

@Autowired
private UserService userService;

@Override
public void onAuthenticationSuccess(HttpServletRequest req, HttpServletResponse resp, Authentication auth)
        throws IOException, ServletException {
    String username= auth.getName();
    User user= userService.findByUsername(username);
    if (user == null) {
        user= new User();
                    //set user properties
    }

    try {
        userService.save(user);
    } catch (EntityException e) {
        System.out.println(e.getMessage());
    }

    super.onAuthenticationSuccess(req, resp, auth);
}
}

I still haven't figured out how to handle AD specific errors (like user is blocked, or password expired), right now it shows my application default login error message.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top