【问题标题】:Custom authentication in SpringSpring中的自定义身份验证
【发布时间】:2011-03-13 10:31:40
【问题描述】:

我有一个问题。在 Struts 中,我有一个处理用户身份验证的操作,即我获取用户的凭据并使用 DAO 来验证用户凭据。我想在 Spring 中保持相同的设置。我正在使用 Spring 3.0.3 RELEASE。

我的问题是,我已经阅读了 Spring Security 并在其中指定了 JDBC 后端“验证”提供程序。我想知道,如果用户单击“登录”,它将如何将凭据提交给我的控制器以检查有效身份验证?

我想这样做的原因是我有一个服务来处理用户身份验证和授权。

提前致谢。

PS 如何在 Spring 中确保某些控制器的安全?
PPS我是 Spring 新手

【问题讨论】:

    标签: java spring spring-mvc spring-security


    【解决方案1】:

    您可以像这样创建实现org.springframework.security.authentication.AuthenticationProvider 的自定义身份验证提供程序

    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));
        }
    
    }
    

    还有一步是配置 spring security 以使用此自定义身份验证提供程序

    <?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">
    
        <!-- 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>
    

    【讨论】:

    • 如果我错了,请纠正我,但我认为这会立即出现在被覆盖的 authenticate() 方法中,而不是控制器中。
    【解决方案2】:

    通常 Spring Security 在自己的代码中处理身份验证,使用您的代码作为策略(身份验证提供程序、用户详细信息服务等)。但是您可以在自己的代码中处理身份验证。

    在您的操作代码中,当用户凭据正确时,您将:

    • 创建一个包含用户名和授予角色的Authentication(您可以使用UsernamePasswordAuthenticationToken 作为一种方便的实现方式)。
    • 将其放入安全上下文中:
      SecurityContextHolder.getContext().setAuthentication(auth);
    • 使用AuthenticationEventPublisher.publishAuthenticationSuccess(...) 广播身份验证成功事件(您可以从上下文自动装配它或显式创建DefaultAuthenticationEventPublisher)。
    • 使用SavedRequestAwareAuthenticationSuccessHandler.onAuthenticationSuccess(...) 将用户重定向到受保护的资源。

    您还需要提供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>
    

    但是,如果您实际上是 Spring 新手,最好避免如此大规模的自定义并使用常规的 Spring Security 架构。

    【讨论】:

      【解决方案3】:

      您可以为 Spring Security 编写自己的验证机制。它必须由以下部分组成:

      • Auth 过滤器 - 从请求中读取数据,然后使用凭证令牌调用 Auth Provider(类 Authentication 的实例)
      • Auth Provider - 接受此身份验证令牌(过滤器可以创建不同的令牌,并且每种令牌类型可以有不同的身份验证提供程序),并尝试进行身份验证(根据您的情况调用您的服务)。身份验证后,您可以(或不可以)致电用户详细信息服务或在此处填写所有用户数据
      • 用户详细信息服务 - 从某处(从 jdbc、其他服务等)加载登录的用户详细信息

      【讨论】:

      • 好的,看到我是@Spring的新手,我该怎么做?
      • @The Elite:这与你的情况无关。
      • @axtavt:精英说他需要使用单独的服务对用户进行身份验证。如果这是真的,那么他至少必须编写自己的 Auth Provider。还是我误解了什么?
      • 正是@splix。有没有教程可以准确地告诉我你提到的分步程序?
      • @The Elite Gentleman 很抱歉唤醒了 2 岁的线程,你有没有找到任何说明如何实现 Auth Provider 的教程
      猜你喜欢
      • 2014-04-20
      • 2014-12-13
      • 1970-01-01
      • 2014-01-12
      • 2016-08-05
      • 2020-12-05
      • 2015-04-27
      • 2017-05-10
      • 2020-04-01
      相关资源
      最近更新 更多