Ron Ziroby Romero
Ron Ziroby Romero

Reputation: 9459

Username Password Authentication in Spring Security

I'm trying to make a simple username/password authentication in a Spring Security web app. I have a web service that authenticates by passing in a user name/password, and gets back a role. Then I need to retain the password for future web service calls.

My app was initially created with App Fuse, so it had some JDBC-based authentication. I've ripped that out, but I'm not sure how to add my custom authentication in.

The documentation says that it's "simple" to add in such a mechanism. But the example app is a command line hello-world style program, not a web app. I can't seem to find an example of username/password authentication in a web app.

I've got the following in my XML file:

<beans:bean id="myProvider" class="com.example.MyProvider"></beans:bean>

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

I don't know if this is the right place to put my authentication in, and I'm not sure what interface to implement. I think I might need to implement AuthenticationManager. And I might use UsernamePasswordAuthenticationToken.

How do I wire this all together?

Upvotes: 4

Views: 18532

Answers (3)

Ron Ziroby Romero
Ron Ziroby Romero

Reputation: 9459

I've got it working now. Thank you everyone for the help. I had to add a new Authentication Provider, and wire it into the Authentication Manager. Here's what I ended up adding:

<beans:bean id="authenticationManager"
     class="org.springframework.security.authentication.ProviderManager">

  <beans:property name="providers">
    <beans:list>
      <beans:ref local="myAuthenticationProvider"/>
    </beans:list>
  </beans:property>
</beans:bean>

<beans:bean id="myAuthenticationProvider" class="com.example.MyAuthenticationProvider">
</beans:bean>

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

and MyAuthenticationProvider (taken from the example) is:

public class AConnexAuthenticationProvider implements AuthenticationProvider {

    static final List<GrantedAuthority> AUTHORITIES = new ArrayList<GrantedAuthority>();

    static {
      AUTHORITIES.add(new GrantedAuthorityImpl("ROLE_USER"));
    }

    @Override
    public Authentication authenticate(Authentication auth)
            throws AuthenticationException {
        return new UsernamePasswordAuthenticationToken(auth.getName(), auth.getCredentials(), AUTHORITIES);
    }

    @Override
    public boolean supports(Class<? extends Object> paramClass) {
        return true;
    }
}

I'll add actual verification of username/password later; this one just lets anyone in.

Upvotes: 4

Fixus
Fixus

Reputation: 4641

This is my security.xml where. Look at configuration of users. I`ve just added controller for processing paths and it works fine.

<http auto-config="true">
    <intercept-url pattern="/admin/**" access="IS_AUTHENTICATED_REMEMBERED"/>
    <intercept-url pattern="/welcome/**" access="IS_AUTHENTICATED_REMEMBERED" />
    <intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
    <form-login login-page="/login" />
    <logout logout-success-url="/" logout-url="/logout" />
    <!-- Limits the number of concurent sessions a user can have
    <concurrent-session-control max-sessions="1" exception-if-maximum-exceeded="true"/>
-->
</http>


<!--
Usernames/Passwords are
    rod/koala
    dianne/emu
    scott/wombat
-->

<authentication-manager>
    <authentication-provider>
        <password-encoder hash="md5"/>
        <user-service>
            <user name="rod" password="a564de63c2d0da68cf47586ee05984d7" authorities="ROLE_SUPERVISOR, ROLE_USER, ROLE_TELLER" />
            <user name="dianne" password="65d15fe9156f9c4bbffd98085992a44e" authorities="ROLE_USER,ROLE_TELLER" />
            <user name="scott" password="2b58af6dddbd072ed27ffc86725d7d3a" authorities="ROLE_USER" />
        </user-service>
    </authentication-provider>
</authentication-manager>

Remember about adding in your web.xml

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
  <filter-name>springSecurityFilterChain</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
    <listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>

Works for me :)

Upvotes: 3

TrueDub
TrueDub

Reputation: 5070

Your provider should implement UserDetailsService, and override the

public UserDetails loadUserByUsername(String username)

method to return a UserDetails object. This is an interface that you can implement on whatever your "user" object is. It requires several methods to be overridden, but the crucial one from your point of view is

public Collection<GrantedAuthority> getAuthorities() 

which you implement to return a list of your roles.

Upvotes: 1

Related Questions