龙空技术网

SpringSecurity核心配置详解

东方猿起 152

前言:

现在小伙伴们对“springsecurity配置解析”可能比较关心,各位老铁们都需要学习一些“springsecurity配置解析”的相关文章。那么小编在网络上网罗了一些有关“springsecurity配置解析””的相关知识,希望朋友们能喜欢,各位老铁们快快来了解一下吧!

为了提高开发效率,现在的项目基本采用springboot的方式开发,本文主要采用SpringBoot方式配置SpringSecurity,然后结合传统的xml配置方式进行比较说明,本文主要讲如何配置,具体类的代码实现会另讲

自定义配置入口

自定义配置需要继承 WebSecurityConfigurerAdapter 进行配置,重写 configure(HttpSecurity http) 方法

springboot写法

@Overrideprotected void configure(HttpSecurity http) throws Exception {        //步骤1: 允许 "/setAuth", "/api/**" 无需要权限访问http.authorizeRequests().antMatchers("/setAuth", "/api/**").permitAll().and()        .authorizeRequests()        // 自定义安全过来拦截        .withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {            @Override            public <O extends FilterSecurityInterceptor> O postProcess(O fsi) {                //步骤2:配置访问决策                fsi.setAccessDecisionManager(accessDecisionManager());                //步骤3:配置权限数据源                fsi.setSecurityMetadataSource(mySecurityMetadataSource());                fsi.setRejectPublicInvocations(true);                return fsi;            }        }).and().formLogin().and().httpBasic() ;        // 禁用CSRF        http.csrf().disable();        //步骤4:配置登录处理入口        http.exceptionHandling().authenticationEntryPoint(new MyLoginUrlAuthenticationEntryPoint())                //步骤5:配置访问拒绝处理                 .accessDeniedHandler(new MyAccessDeniedHandler())                //步骤6:配置退出访问地址                 .and().logout().logoutUrl("/logout")                //步骤7:配置退出跳转地址                .logoutSuccessUrl("/loginAjax");        // 步骤8:配置登录成功处理        http.formLogin().successHandler(authenticationSuccessHandler());        // 步骤9:配置登录失败处理        http.formLogin().failureHandler(authenticationFailureHandler());    }

xml写法

<!-- 允许 "/setAuth", "/api/**" 无需要权限访问 --><http pattern="/setAuth" security="none"/><http pattern="/api/**" security="none"/><http auto-config="true" entry-point-ref="myLoginUrlAuthenticationEntryPoint">        <!-- 访问拒绝处理 -->        <access-denied-handler ref="accessDeniedHandler" />        <!--form登录        login-page: 登录访问地址        authentication-failure-url:认证失败跳转地址        authentication-success-handler-ref: 认证成功处理类        -->        <form-login                    login-page="${security.loginFormUrl}"                    authentication-failure-url="${security.loginFormUrl}?login_error=1"                    authentication-success-handler-ref="httpAuthenticationSuccessHandler"                    default-target-url="${security.defaultTargetUrl}"                    always-use-default-target="false"        />        <!-- 退出成功跳转地址 -->        <logout logout-success-url="${security.loginFormUrl}"/>        <http-basic />        <!-- 自定义安全过来拦截 -->        <custom-filter before="FILTER_SECURITY_INTERCEPTOR" ref="filterSecurityInterceptor"/>    </http>
访问决策配置

自定义访问决策实现AccessDecisionManager接口,通过登录用户具备的权限和访问资源需要的权限进行比较决策

springboot写法

public AccessDecisionManager accessDecisionManager() {        return new AccessDecisionManager();}

xml写法

<beans:bean id="accessDecisionManager" class="com.vstore.boot.autoconfigure.security.AccessDecisionManager"/>
权限元数据来源配置

自定义权限元数据来源实现 FilterInvocationSecurityMetadataSource 接口,关键重写public Collection<ConfigAttribute> getAttributes(Object object) 方法,该方法返回访问资源所需要的权限

springboot写法

public MySecurityMetadataSource mySecurityMetadataSource() {    return  new MySecurityMetadataSource(dataSource,securityProperties.getLoadAllResourceQuery());    }

MySecurityMetadataSource 第一参数是数据源,第二参数是一个查询sql语句,根据表结构SQL语句是下面这样的,查询出资源和权限对应列表

 select resource_url as  url,permission_code code from  sys_permission p      left join sys_permission_resource pr on p.id=pr.permission_id      left join sys_resource  r  on r.id=pr.resource_id      where resource_url is not null

resource_url是请求资源,permission_code是资源对应权限,MySecurityMetadataSource 中的getAttributes(Object object) 方法返回资源所需要的权限。

xml写法

<beans:bean id="invocationSecurityMetadataSourceService" class="com.vstore.boot.autoconfigure.security.MySecurityMetadataSource">        <beans:constructor-arg index="0">            <beans:ref bean="dataSource" />        </beans:constructor-arg>        <beans:constructor-arg index="1">            <beans:value>${security.loadAllResourceQuery}</beans:value>        </beans:constructor-arg>    </beans:bean>
登录入口配置

由于项目是一个前后端分离的项目,这边实现 AuthenticationEntryPoint 接口,返回一个json格式,前端通过json解析跳转到登录页面

public class MyLoginUrlAuthenticationEntryPoint    implements AuthenticationEntryPoint {    @Override    public void commence(HttpServletRequest request, HttpServletResponse response,                         AuthenticationException authException) throws IOException, ServletException {        response.setCharacterEncoding("utf-8");        response.setContentType("text/javascript;charset=utf-8");        Response<String> responseMsg=new Response<>();        responseMsg.setResult("没有登录");        responseMsg.setResCode(403);        response.getWriter().print(JsonUtils.convert2String(responseMsg)   );    }}
登录成功和失败处理

登录成功和失败都会有相应的接口,成功的接口:AuthenticationSuccessHandler ,失败的接口:AuthenticationFailureHandler,实现对应的接口,在配置指定对应实现类即可。

举例:登录失败配置指定

// 步骤9:配置登录失败处理http.formLogin().failureHandler(authenticationFailureHandler());

authenticationFailureHandler()实现

public AuthenticationFailureHandler authenticationFailureHandler(){        return new AuthenticationFailureHandler() {            @Override            public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {                response.setCharacterEncoding("utf-8");                response.setContentType("text/javascript;charset=utf-8");                Response<String> responseMsg=new Response<>();                responseMsg.setResult(exception.getMessage());                responseMsg.setResCode(403);                response.getWriter().print(JsonUtils.convert2String(responseMsg)   );            }        };    }

年轻商人的侧面, 用电脑与商业图表在屏幕上的现代办公室与木制办公桌和砖墙。财务概念。双曝光

标签: #springsecurity配置解析 #spring security配置详解