views:

107

answers:

4

Hi everyone,

I have a question. In Struts, I have an Action that deals with user authentication, i.e., I took the user's credentials and used a DAO to validate user credentials. I want to maintain the same setup in Spring. I'm using Spring 3.0.3 RELEASE.

My question is, I've read Spring Security and in there it specifies JDBC backend "Validation" provider. I want to know, how would, if the user clicked "login" that it submits the credentials to my controller to check for valid authentication?

The reason I want to do this that way is that I have a Service that handles user authentication and authorization.

Thanks in advance.

PS How do I make some controller secure in Spring?
PPS I'm new to Spring

A: 

You can write you own validation mechanism for Spring Security. It have to consists of following parts:

  • Auth Filter - reads data from request, then call Auth Provider with credentials token (instance of class Authentication)
  • Auth Provider - accepts this auth token (filter can create different tokents, and there can be different auth providers, for each token type), and try to authenticate (calling your service, at your case). After auth you may (or may not) call User Details Service or fill all user data right there
  • User Details Service - load signed in user details from somewhere (from jdbc, other service, etc)
splix
Ok, Seeing that I'm a newbie @ Spring, how would I do this?
The Elite Gentleman
@The Elite: It's not about your case.
axtavt
@axtavt: The Elite said that he need to authenticate users using an separate Service. If this is true, then he have to write at least his own Auth Provider. Or i misunderstood something?
splix
Exactly @splix. Is there a tutorial that can show me exactly the step by step procedures you've mentioned?
The Elite Gentleman
A: 

Usually Spring Security handles authentication inside its own code, using your code as strategies (authentication providers, user details services, etc). But you can handle authentication inside your own code.

In your action's code, when user credentials are correct, you will:

  • Create an Authentication containing user name and granted roles (you may use UsernamePasswordAuthenticationToken as a convenient implementation).
  • Put it into security context:
    SecurityContextHolder.getContext().setAuthentication(auth);
  • Broadcast the authentication success event using AuthenticationEventPublisher.publishAuthenticationSuccess(...) (you may autowire it from the context or create a DefaultAuthenticationEventPublisher explicitly).
  • Redirect user to the secured resource using SavedRequestAwareAuthenticationSuccessHandler.onAuthenticationSuccess(...).

Also you need to supply an AuthenticationEntryPoint:

<bean id = "aep" class = "org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
     <!-- Your login page -->
     <property name = "loginFormUrl" value = "/login" />
</bean>

<security:http entry-point-ref="aep">
    ...
</http>

However, if you are actually new in Spring, it may be better to avoid such a massive customizations and use the regular Spring Security architecture.

axtavt
A: 

@Elite, this simple tutorial will help you to get started: http://www.mularien.com/blog/2008/07/07/5-minute-guide-to-spring-security/

Keep in mind when you specify the intercept-url patterns, the order is important where you place the most granular (restrictive) access on the top and usually you will have a "catch-all" as the last intercept-url pattern.

I stole this snippet from that tutorial link, and as you can see, the /**.do at the bottom is the catch-all pattern.

<http auto-config="true" access-denied-page="/accessDenied.jsp">
        <intercept-url pattern="/login.jsp*" filters="none"/>  
        <intercept-url pattern="/admin/editUser.do" access="ROLE_ADMIN"  />
        <intercept-url pattern="/admin/searchUsers.do" access="ROLE_ADMIN"  />
        <intercept-url pattern="/**.do" access="ROLE_USER,ROLE_ADMIN"  />
        <form-login authentication-failure-url="/login.jsp?login_error=1" default-target-url="/home.do"/>
        <logout logout-success-url="/home.do"/>
</http>
limc
+1  A: 

You can create a custom authentication provider that implements org.springframework.security.authentication.AuthenticationProvider like this

package com.bzone.example;

import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;


public class CustomAuthenticationProvider implements AuthenticationProvider{

    @Override
    public Authentication authenticate(Authentication authentication)
            throws AuthenticationException {
        // TODO call custom service or do whatever you want 
        return null;
    }

    @Override
    public boolean supports(Class<? extends Object> authentication) {
        // copied it from AbstractUserDetailsAuthenticationProvider
        return (UsernamePasswordAuthenticationToken.class.isAssignableFrom(authentication));
    }

}

one more step is to configure spring security to use this custom authentication provider

<?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"&gt;

    <!-- HTTP security configurations -->
    <http auto-config="true" use-expressions="true">
        <form-login login-processing-url="/static/j_spring_security_check" login-page="/login" authentication-failure-url="/login?login_error=t"/>
        <logout logout-url="/static/j_spring_security_logout"/>

        <!-- Configure these elements to secure URIs in your application -->
        <intercept-url pattern="/member/**" access="isAuthenticated()" />
        <intercept-url pattern="/resources/**" access="permitAll" />
        <intercept-url pattern="/static/**" access="permitAll" />
        <intercept-url pattern="/**" access="permitAll" />
    </http>

    <!-- Configure Authentication mechanism -->
    <authentication-manager alias="authenticationManager">
        <authentication-provider ref="com.bzone.example.CustomAuthenticationProvider" />
    </authentication-manager>

</beans:beans>
Barakat