Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring - Security : how are login username and password bound to the authentication-provider?

I am new to spring and spring security,

I have understood how beans are created and referenced in the xml files, I need to provide security using spring into my application.

I included a custom applicationContext-security.xml file in my web.xml : contextConfigLocation

in this file, I have intercepted url patterns using

<intercept-url pattern='/**.something' access="IS_AUTHENTICATED_FULLY"/>

inside element.

I have set the form for login as now, if a page is not authorised it shows me my custom Login.html page.

Now for the issues I am facing:

  1. How do I specify my login form to pass its value to spring ?
  2. How do I use my own authentication-provider ?

I tried this:

<authentication-provider user-service-ref="userDetailsService"/>
<beans:bean id = "userDetailsService" class ="com.somepath.CustomAuthenticationProvider">
        <custom-authentication-provider/>
    </beans:bean>

where CustomAuthenticationProvider implements AuthenticationProvider

but the code throws an error: Error creating bean with name '_filterChainProxy' .... No UserDetailsService registered

Please help

like image 865
Salvin Francis Avatar asked Oct 21 '09 08:10

Salvin Francis


2 Answers

1: How do I specify my login form to pass its value to spring ?

After you setup your standard Spring Filter in web.xml for Spring Security, using some of the default settings configured by the <http> tag. An instance of AuthenticationProcessingFilter is created for you as part of the chain of filters.

My default the AuthenticationProcessingFilter is set up to read j_username and j_password as the username / password token.

In order to override this, replace your customize AuthenticationProcessingFilter over the default one by doing this:

<bean id=“myAuthFilter” class=“org.springframework.security.ui.webapp.AuthenticationProcessingFilter” >
<security:custom-filter position=“AUTHENTICATION_PROCESSING_FILTER”/><!–-replace the default one-–>
  <property name=“usernameParameter” value=“myUsername”/><!-- myUsername is the name of the input tag where user enter their username on the HTML page -->
  <property name=“passwordParameter” value=“myPassword” /><!–- myPassword is the name of the input tag where user enter their password on the HTML page -–>
</bean>

See also the JavaDoc of AuthenticationProcessingFilter for more details: http://static.springsource.org/spring-security/site/apidocs/org/springframework/security/ui/webapp/AuthenticationProcessingFilter.html

2: How do I use my own authentication-provider?

Using the following code:

<bean id="myAuthenticationProvider" class="com.something.MyAuthenticationProvider">
    <security:custom-authentication-provider />
</bean>

<security:custom-authentication-provider /> is the tag that let's spring knows this is a custom provider and the Authentication Manager should use it in its provider chain.

Source: http://static.springsource.org/spring-security/site/docs/2.0.x/reference/appendix-namespace.html#d4e3379

3: Regarding the issue with the code throwing '_filterChainProxy' .... No UserDetailsService registered...'

Is com.somepath.CustomAuthenticationProvider implementing the UserDetailService interface?

like image 129
lsiu Avatar answered Oct 29 '22 08:10

lsiu


I am somewhat new to Spring myself but I will try to help you. The intercept-url looks fine.

I don't think the authentication-provider is right. Take a look at my code:

  <beans:bean id="MyUserDetailsService" class="path.to.MyAuthenticationService"/>

<beans:bean id="userDetailsService" class="org.springframework.security.userdetails.hierarchicalroles.UserDetailsServiceWrapper" >
    <beans:property name="roleHierarchy" ref="roleHierarchy" />
    <beans:property name="userDetailsService">
      <beans:ref bean="MyUserDetailsService"/>
    </beans:property>
  </beans:bean>
 <authentication-provider user-service-ref="userDetailsService">
   <password-encoder hash="md5"/>
 </authentication-provider>

You may not need the role heirarchy.

You have a login form on a jsp page. The form should begin something like this:

<form:form modelAttribute="login">

Also you must map the appropriate fields.

<form:input path="login">
<form:password path="password">

in your applicationContext-security.xml set the login page:

<form-login login-page="/login.jsp" default-target-url="/login.html" always-use-default-target="true" authentication-failure-url="/login.jsp?login_error=1"/>

login.html should be mapped to your LoginController.java which extends BaseController and implements a login method which takes at least a HttpServletRequest and Model as parameters. Mine then works by calling the following Spring class/methods:

String userlogin = SecurityContextHolder.getContext().getAuthentication().getName();

If your CustomAuthenticationProvider is implemented correctly you can then (hopefully) get the user's details from your Model and finally:

return "redirect:homepage.html";

I may have missed something if you're still having trouble let me know in a comment.

like image 42
RobbR Avatar answered Oct 29 '22 09:10

RobbR