Announcement Announcement Module
Collapse
No announcement yet.
Spring-security SAML: No AuthenticationProvider found for UsernamePasswordAuthentica Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring-security SAML: No AuthenticationProvider found for UsernamePasswordAuthentica

    I am using vaadin UI library in my project. I want to implement that on form submit (button click) spring-saml extension will check if user is authenticated. If not it will redirect to authetication form. For this reason i use code snippet below:

    Code:
    public void onLogin(LoginEvent event)
        {						
    	if (event.getLoginParameter("username").isEmpty() || event.getLoginParameter("password").isEmpty()) 
    		{
                        getWindow().showNotification("Please enter username and password", Notification.TYPE_ERROR_MESSAGE);
    		}
    	else
    		{							
    		    try
    			{
    				SpringContextHelper helper = new SpringContextHelper(getApplication());
    				authenticationManager = (ProviderManager)helper.getBean("authenticationManager");
                                    UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(event.getLoginParameter("username"),  event.getLoginParameter("password"));	 
    				Authentication authentication = authenticationManager.authenticate(token);        //exception comes here
    				SecurityContextHolder.getContext().setAuthentication(authentication);
    				authentication.getDetails();
    										
    			}
    		    catch (Exception e)
    			{
    				getWindow().showNotification(e.getMessage(), Notification.TYPE_ERROR_MESSAGE);
    			}
    		}					
        }
    The authenticationManager I describe in securityContext.xml:

    Code:
    <context:annotation-config/>
    <context:component-scan base-package="org.springframework.security.saml"/>
    
    <security:authentication-manager alias="authenticationManager">
            <security:authentication-provider ref="samlAuthenticationProvider"/>
    </security:authentication-manager>
    
    <bean id="samlAuthenticationProvider" class="org.springframework.security.saml.SAMLAuthenticationProvider">
            <!-- OPTIONAL property: can be used to store/load user data after login -->
            <!--
            <property name="userDetails" ref="bean" />
            -->
     </bean>
    So when I push the button I got "No AuthenticationProvider found for UsernamePasswordAuthenticationToken" exception. It looks like that calss SAMLAuthenticationProvider cannot be resolved. So what i am doing wrong? Maybe I am doing bad conversion from (ProviderManager)helper.getBean("authenticationMan ager");. Maybe I should use something like that (SAMLAuthenticationManager)helper.getBean("authent icationManager");. But I can't find such class SAMLAuthenticationManager. Or maybe It is impossible to do such thing in way that I do. I am new to spring and spring security sorry if the questions looks dumb.

  • #2
    The SAMLAuthneticationProvider expects token of type SAMLAuthnicationToken and doesn't support UsernamePasswordAuthenticationToken. With SAML you do not perform authentication locally in your application, but instead rely on a remote identity provider (IDP). In case you want to get your user authenticated you should simply redirect her to scheme://serverort/context/saml/login which will typically (depending on configuration) initialize login with your default IDP.

    In case your use-case is to support both local username-password authentication with additional support for SAML, you would need to add additional authentication provider to the authentication manager bean. You can find details in the Spring Security manual.

    E.g.:
    Code:
        <!-- Register authentication manager with SAML provider -->
        <security:authentication-manager alias="authenticationManager">
            <security:authentication-provider ref="samlAuthenticationProvider"/>
            <security:authentication-provider>
                <security:user-service>
                    <security:user name="test" password="abcd123" authorities="ROLE_USER" />
                </security:user-service>
            </security:authentication-provider>
        </security:authentication-manager>

    Comment


    • #3
      Originally posted by vsch View Post
      The SAMLAuthneticationProvider expects token of type SAMLAuthnicationToken and doesn't support UsernamePasswordAuthenticationToken. With SAML you do not perform authentication locally in your application, but instead rely on a remote identity provider (IDP). In case you want to get your user authenticated you should simply redirect her to scheme://serverort/context/saml/login which will typically (depending on configuration) initialize login with your default IDP.

      In case your use-case is to support both local username-password authentication with additional support for SAML, you would need to add additional authentication provider to the authentication manager bean. You can find details in the Spring Security manual.

      E.g.:
      Code:
          <!-- Register authentication manager with SAML provider -->
          <security:authentication-manager alias="authenticationManager">
              <security:authentication-provider ref="samlAuthenticationProvider"/>
              <security:authentication-provider>
                  <security:user-service>
                      <security:user name="test" password="abcd123" authorities="ROLE_USER" />
                  </security:user-service>
              </security:authentication-provider>
          </security:authentication-manager>
      Basically I don't need any local user authetication. I just need authenticate them againt remote IDP. I changed UsernamePasswordAuthenticationToken to SAMLAuthnicationToken as you suggested and now I get "Invalid SAML message" error. That's ok, because I didn't pass any preformatted SAML message. So my guess would be to use available SAMLAuthnicationToken methods to form a correct SAML message (with encapsulated user credential parameters) and to send it directly to IDP not using any login page redirection and etc. In short I want to use your extension as library which will help me to connect, authenticate and exchange information to remote IDP like kind of webservice. I think this is possible. What do you think?

      Comment


      • #4
        You can start authentication with IDP programatically - check sources for SAMLEntryPoint class. The other (easier) way is to send user to the URL I mentioned above. SAMLAuthenticationToken needs to be populated from SAML message provided by IDP, you cannot construct it by hand.

        SAML Web Single Sign-On doesn't work as a web-service which you call with credentials and receive a response. The key idea behind federations is for the service provider to not have access to the user's credentials and only rely on the IDP saying "I have authenticated this user". This information is expressed by IDP as a SAML assertion and sent to SP.

        Vladimir Schäfer

        Comment


        • #5
          Originally posted by vsch View Post
          You can start authentication with IDP programatically - check sources for SAMLEntryPoint class. The other (easier) way is to send user to the URL I mentioned above. SAMLAuthenticationToken needs to be populated from SAML message provided by IDP, you cannot construct it by hand.

          SAML Web Single Sign-On doesn't work as a web-service which you call with credentials and receive a response. The key idea behind federations is for the service provider to not have access to the user's credentials and only rely on the IDP saying "I have authenticated this user". This information is expressed by IDP as a SAML assertion and sent to SP.

          Vladimir Schäfer
          Now it becomes much more clear for me. So now I think have to do like this: when user wants to access my vaadin application resources then i have to check inside Vaadin app if the user is allready autheticated with my IDP using spring-saml provided methods. If it is then I have to redirect (or give access) to further vaadin resources. If it is not autheticated then I have to redirect it to scheme://serverort/context/saml/login url which will initialize default IDP. And after successful login IDp has to redirect me back to my vaadin app?
          Last edited by freeland; Jan 25th, 2013, 03:26 AM.

          Comment


          • #6
            That's right. After successful authentication IDP will redirect you back to the app (to the SAMLProcessingFilter) which will verify the IDP response. After verification the AuthenticationSuccessHandler is invoked and returns control to your application. You can customize it in bean successRedirectHandler.

            Comment

            Working...
            X