去除Spring Security认证:Pre-Authentication配置

栏目: 后端 · 发布时间: 5年前

内容简介:Spring Security官方文档对Pre-Authentication是这样解释的:这里面涉及到Spring Security中两个概念,认证(Authentication)和授权(Authorization)。有关这两个概念的介绍,网上可以搜索到其他相关资料,这里仅通俗易懂的解释一下:Spring Security框架提供了认证和授权的功能,但是有可能只希望使用Spring Security的授权功能,而不使用它提供的认证功能,比如使用一些其他认证方式,那么就可以使用Pre-Authenticat

Spring Security官方文档对Pre-Authentication是这样解释的:

There are situations where you want to use Spring Security for authorization, but the user has already been reliably authenticated by some external system prior to accessing the application. We refer to these situations as “pre-authenticated” scenarios.

这里面涉及到Spring Security中两个概念,认证(Authentication)和授权(Authorization)。有关这两个概念的介绍,网上可以搜索到其他相关资料,这里仅通俗易懂的解释一下:

  • 认证(Authentication):认证就是判断用户身份是否合法,例如用户名密码登录就是认证,如果一个用户拥有正确的密码,即可通过认证;
  • 授权(Authorization):用户认证通过了,但是每个用户的权限不同,判断用户有哪些权限以及是否有权限访问某些资源,就是授权。

Spring Security框架提供了认证和授权的功能,但是有可能只希望使用Spring Security的授权功能,而不使用它提供的认证功能,比如使用一些其他认证方式,那么就可以使用Pre-Authentication。

Pre-Authentication配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:security="http://www.springframework.org/schema/security"
       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.xsd
        http://www.springframework.org/schema/security
        http://www.springframework.org/schema/security/spring-security.xsd">

    <security:http entry-point-ref="http403ForbiddenEntryPoint">
        <!-- 省略其他配置 -->
        <security:custom-filter position="PRE_AUTH_FILTER" ref="preauthFilter" />
    </security:http>
    <bean id="http403ForbiddenEntryPoint" class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint" />
    <bean id="preauthFilter" class="com.xxg.test.auth.PreauthFilter">
        <property name="authenticationManager" ref="authenticationManager" />
    </bean>

    <bean id="preauthAuthProvider" class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
        <property name="preAuthenticatedUserDetailsService">
            <bean id="userDetailsServiceWrapper" class="org.springframework.security.core.userdetails.UserDetailsByNameServiceWrapper">
                <property name="userDetailsService" ref="userDetailsService"/>
            </bean>
        </property>
    </bean>
    <bean id="userDetailsService" class="com.xxg.test.auth.UserDetailsServiceImpl" />
    <security:authentication-manager alias="authenticationManager">
        <security:authentication-provider ref="preauthAuthProvider" />
    </security:authentication-manager>

</beans>

由于不再使用Spring Security提供的默认的用户名密码登录认证,需要修改 entry-point-refHttp403ForbiddenEntryPoint ,否则会出现异常:

No AuthenticationEntryPoint could be established. Please make sure you have a login mechanism configured through the namespace (such as form-login) or specify a custom AuthenticationEntryPoint with the ‘entry-point-ref’ attribute

配置Pre-Authentication的最主要的部分是需要添加一个 position="PRE_AUTH_FILTER" 的Filter,这个Filter继承抽象类 AbstractPreAuthenticatedProcessingFilter

public class PreauthFilter extends AbstractPreAuthenticatedProcessingFilter {

    /**
    * 重写,返回用户名,这个用户名是经过其他方式认证过
    */
    @Override
    protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
        if (authenticated) {
            // 可以通过request获取当前认证过的用户名,比如通过参数、HTTP请求头或者Cookie获取token,再通过token调用第三方接口获取用户名
            return "your_username";
        } else {
            // 如果认证失败,可以抛出异常
            throw new PreAuthenticatedCredentialsNotFoundException("认证失败");
        }
    }

    /**
    * 这个方法一般情况下不需要重写,直接返回空字符串即可
    */
    @Override
    protected Object getPreAuthenticatedCredentials(HttpServletRequest request) {
        return "";
    }
}

另外还有个重点配置 userDetailsService ,这个是用于用户认证后的授权。这里需要一个 UserDetailsService 的实现类,来获取用户的所有权限。

public class UserDetailsServiceImpl implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        // 这里可以通过用户名获取对应的权限
        Collection<GrantedAuthority> auths = new ArrayList<>();
        auths.add(new SimpleGrantedAuthority("ROLE_USER"));
        auths.add(new SimpleGrantedAuthority("ROLE_SUPER_ADMIN"));

        User user = new User(username, "", auths);
        return user;
    }
}

使用场景

如果是普通的浏览器访问的Web,以上完成配置后,用户在浏览器上首次访问会调用 AbstractPreAuthenticatedProcessingFiltergetPreAuthenticatedPrincipal 以及 UserDetailsServiceloadUserByUsername 方法来获取认证用户和授权,并将相关信息保存到Session中,后续的请求直接通过Session获取用户信息,不再重复调用这些方法。

而对于API接口来说,一般情况下不会使用Session来做会话控制,例如可能会通过token的方式。API接口相对来说每次接口访问都是无状态的,所以针对每次请求都需要重新认证和授权。这个时候可以设置 create-session="stateless" 来禁掉Spring Security使用Session:

<security:http entry-point-ref="http403ForbiddenEntryPoint" create-session="stateless">
    <!-- 省略其他配置 -->
    <security:custom-filter position="PRE_AUTH_FILTER" ref="preauthFilter" />
</security:http>

参考资料


以上所述就是小编给大家介绍的《去除Spring Security认证:Pre-Authentication配置》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

XMPP

XMPP

Peter Saint-Andre、Kevin Smith、Remko TronCon / O'Reilly Media / 2009-5-4 / USD 39.99

This practical book provides everything you need to know about the Extensible Messaging and Presence Protocol (XMPP). This open technology for real-time communication is used in many diverse applicati......一起来看看 《XMPP》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

URL 编码/解码
URL 编码/解码

URL 编码/解码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器