spring security 入門教程

原文地址:spring security 入門教程
本篇文章只作為spring security入門使用,具體深入內(nèi)容請(qǐng)自行查詢相關(guān)資料。

目錄:

  • spring security簡(jiǎn)介
  • 接入方式
  • 用戶存儲(chǔ)認(rèn)證方式
  • 密碼加密策略
  • 請(qǐng)求攔截策略
  • 強(qiáng)制安全性通道
  • 防止CSRF
  • remember-me功能
  • 自定義登錄頁(yè)面

1、spring security簡(jiǎn)介

Spring Security是一個(gè)能夠?yàn)榛赟pring的企業(yè)應(yīng)用系統(tǒng)提供聲明式的安全訪問(wèn)控制解決方案的安全框架。它提供了一組可以在Spring應(yīng)用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反轉(zhuǎn)Inversion of Control ,DI:Dependency Injection 依賴注入)和AOP(面向切面編程)功能,為應(yīng)用系統(tǒng)提供聲明式的安全訪問(wèn)控制功能,減少了為企業(yè)系統(tǒng)安全控制編寫大量重復(fù)代碼的工作。當(dāng)前版本為4.2.3。

2、接入方式

Spring Security的接入方式一共有兩種:基于注解方式和基于xml配置方式。下面對(duì)兩種接入方式作一下介紹。
首先是spring security依賴引入
pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>demo.security</groupId>
    <artifactId>security</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <properties>
        <!-- spring版本號(hào) -->
        <spring.version>4.1.6.RELEASE</spring.version>
        <security.version>4.0.1.RELEASE</security.version>
        <!-- log4j日志文件管理包版本 -->
        <slf4j.version>1.7.7</slf4j.version>
        <log4j.version>1.2.17</log4j.version>

    </properties>

    <dependencies>
    <!-- springframework -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-oxm</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-tx</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-core</artifactId>
        <version>${security.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-config</artifactId>
        <version>${security.version}</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-taglibs</artifactId>
        <version>${security.version}</version>
    </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>3.0-alpha-1</version>
            <scope>provided</scope>
        </dependency>
        <!-- 導(dǎo)入Mysql數(shù)據(jù)庫(kù)鏈接jar包 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.30</version>
        </dependency>
    </dependencies>

    <build>
        <finalName>ROOT</finalName>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>config/${env}</directory>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
        </resources>
    </build>

        </project>

這里使用的是servlet3.0,自servlet3.0+規(guī)范后,允許servlet,filter,listener不必聲明在web.xml中,而是以硬編碼的方式存在,實(shí)現(xiàn)容器的零配置。

2.1、基于注解方式

第一步是要?jiǎng)?chuàng)建Spring Security的Java 配置類。
創(chuàng)建類SecurityConfiguration繼承WebSecurityConfigurerAdapter,來(lái)對(duì)我們應(yīng)用中所有的安全相關(guān)的事項(xiàng)(所有url,驗(yàn)證用戶名密碼,表單重定向等)進(jìn)行控制。

SecurityConfiguration.java

package com.security.code;

import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

import javax.sql.DataSource;

/**
 * <li>security config</li>
 *
 * @author lixin
 * @create 17/3/22
 */
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter{

    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    /**
     * 配置user-detail服務(wù)
     * @param auth
     * @throws Exception
     */
    @Override
    public void configure(AuthenticationManagerBuilder auth)throws Exception{
        
    }

    /**
     * 攔截請(qǐng)求
     * @param http
     * @throws Exception
     */
    @Override
    public void configure(HttpSecurity http)throws Exception{
        
    }

    /**
     * 攔截請(qǐng)求
     * @param web
     * @throws Exception
     */
    @Override
    public void configure(WebSecurity web) throws Exception {

    }
}

WebSecurityConfigurerAdapter共有三個(gè)configure方法。

configure(WebSecurity) 通過(guò)重載,配置Spring Security的Filter鏈
configure(HttpSecurity) 通過(guò)重載,配置如何通過(guò)攔截器保護(hù)請(qǐng)求
configure(AuthenticationManagerBuilder) 通過(guò)重載,配置user-detail服務(wù)

@EnableWebSecurity 注解將會(huì)啟用Web安全功能。

第二步是初始化springSecurityFilter注冊(cè)類,這里使用的方法是繼承類AbstractSecurityWebApplicationInitializer

package com.security.code;

import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;

/**
 * <li>注冊(cè)springSecurityFilter</li>
 *
 * @author lixin
 * @create 17/3/22
 */
public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer
{
}

這里可以沒(méi)有任何實(shí)現(xiàn)。至此,基于注解方式的接入就完成了。下面介紹一下基于xml配置方式的接入。

2.2、基于xml配置方式接入

第一步,在web.xml加入配置

<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

第二步,增加spring-security.xml,并引入到application.xml內(nèi)

spring-security.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:security="http://www.springframework.org/schema/security"
       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 auto-config="true" use-expressions="true">
        ...
    </security:http>

    <security:authentication-manager>
        ..
    </security:authentication-manager>

</beans>

具體配置后續(xù)會(huì)添加。基于xml配置方式就這么多,下面介紹一下用戶的存儲(chǔ)認(rèn)證方式。

3、用戶存儲(chǔ)認(rèn)證方式

spring security關(guān)于用戶存儲(chǔ)認(rèn)證方面是非常靈活的,能夠基于各種數(shù)據(jù)存儲(chǔ)來(lái)認(rèn)證用戶。它內(nèi)置了多種常見的用戶存儲(chǔ)場(chǎng)景,下面對(duì)各種場(chǎng)景進(jìn)行下介紹。

3.1、使用基于內(nèi)存的用戶存儲(chǔ)

從名稱上可以知道這種方式是將用戶名、密碼、權(quán)限等數(shù)據(jù)存儲(chǔ)在內(nèi)存中,一般個(gè)人開發(fā)測(cè)試可以使用這種方式。

注解編碼方式:

    /**
     * 配置user-detail服務(wù)
     * @param auth
     * @throws Exception
     */
    @Override
    public void configure(AuthenticationManagerBuilder auth)throws Exception{
        //基于內(nèi)存的用戶存儲(chǔ)、認(rèn)證
        auth.inMemoryAuthentication()
                .withUser("admin").password("admin").roles("ADMIN","USER")
                .and()
                .withUser("user").password("user").roles("USER");
    }

代碼里通過(guò)方法auth.inMemoryAuthentication()獲取AuthenticationManagerBuilder對(duì)象,并設(shè)置了兩個(gè)用戶admin和user同時(shí)設(shè)置對(duì)應(yīng)密碼和所擁有的權(quán)限。

這里需要注意的是,roles()方法是authorities()方法的簡(jiǎn)寫形式。roles()方法所給定的值都會(huì)加一個(gè)"ROLE_"前綴,并將其作為權(quán)限授予用戶。實(shí)際上,如下用戶配置與上面程序是一樣的。

    /**
     * 配置user-detail服務(wù)
     * @param auth
     * @throws Exception
     */
    @Override
    public void configure(AuthenticationManagerBuilder auth)throws Exception{
         //基于內(nèi)存的用戶存儲(chǔ)、認(rèn)證
        auth.inMemoryAuthentication()
                .withUser("admin").password("admin").authorities("ROLE_AMIN","ROLE_USER")
                .and()
                .withUser("user").password("user").authorities("ROLE_USER");

    }

除了上面的方法還有一些其它方法可以配置用戶的詳細(xì)信息。

accountExpired(boolean) 定義賬號(hào)是否已經(jīng)過(guò)期
accountLocked(boolean) 定義賬號(hào)是否已經(jīng)鎖定
and() 用來(lái)連接配置
authorities(GrantedAuthority...) 授予某個(gè)用戶一項(xiàng)或多項(xiàng)權(quán)限
authorities(List<? extends GrantedAuthority>) 授予某個(gè)用戶一項(xiàng)或多項(xiàng)權(quán)限
authorities(String...) 授予某個(gè)用戶一項(xiàng)或多項(xiàng)權(quán)限
credentialsExpired(boolean) 定義憑證是否已經(jīng)過(guò)期
disabled(boolean) 定義賬號(hào)是否已被禁用
password(String) 定義用戶的密碼
roles(String...) 授予某個(gè)用戶一項(xiàng)或多項(xiàng)角色

xml配置方式:

    <security:authentication-manager>
        <security:authentication-provider>
            <security:user-service>
                <security:user name="admin" authorities="ROLE_ADMIN" password="admin"/>
                <security:user name="user" authorities="ROLE_USER" password="user"/>
            </security:user-service>
        </security:authentication-provider>
    </security:authentication-manager>

3.2、基于數(shù)據(jù)庫(kù)表用戶存儲(chǔ)認(rèn)證

通常我們都會(huì)將用戶數(shù)據(jù)存儲(chǔ)在關(guān)系型數(shù)據(jù)庫(kù)中,并通過(guò)jdbc進(jìn)行訪問(wèn)。spring security使用以jdbc為支撐的用戶存儲(chǔ),我們可以使用下面的方式進(jìn)行配置。

基于注解編碼方式:

    /**
     * 配置user-detail服務(wù)
     * @param auth
     * @throws Exception
     */
    @Override
    public void configure(AuthenticationManagerBuilder auth)throws Exception{
        //基于數(shù)據(jù)庫(kù)的用戶存儲(chǔ)、認(rèn)證
        auth.jdbcAuthentication().dataSource(dataSource)
                .usersByUsernameQuery("select account,password,true from user where account=?")
                .authoritiesByUsernameQuery("select account,role from user where account=?");
    }

第一個(gè)查詢語(yǔ)句獲取了用戶的基本信息,第二個(gè)查詢語(yǔ)句獲取了用戶權(quán)限數(shù)據(jù)。

基于xml配置方式:

<security:authentication-manager>
        <security:authentication-provider>
            <security:jdbc-user-service data-source-ref="dataSource"
                                        authorities-by-username-query="select account,role from user where account=?"
                                        users-by-username-query="select account,password,true from user where account=?"/>
            <security:password-encoder ref="bcryptEncoder"/>
    </security:authentication-manager>

3.3、基于LDAP進(jìn)行用戶存儲(chǔ)認(rèn)證

這種方式?jīng)]有進(jìn)行測(cè)試,如果感興趣可以自行測(cè)試。

3.4、配置自定義的用戶存儲(chǔ)認(rèn)證

這種方式更為靈活,更適合在生產(chǎn)環(huán)境使用。這種方式不在局限于存儲(chǔ)環(huán)境。自定義的方式也很簡(jiǎn)單。只需要提供一個(gè)UserDetailService接口實(shí)現(xiàn)即可。

package com.blog.admin.security;

import com.blog.admin.dao.UserDao;
import db.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

/**
 * <li></li>
 *
 * @author lixin
 * @create 17/3/20
 */
@Service
public class BlogSecurityUserDetailsService implements UserDetailsService{

    @Autowired
    private UserDao userDao;

    /**
     * 校驗(yàn)用戶
     * @param username
     * @return
     * @throws UsernameNotFoundException
     */
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        User user = userDao.queryByUserName(username);
        if(user == null)throw new UsernameNotFoundException("user not found");

        return new org.springframework.security.core.userdetails.User(user.getAccount(),user.getPassword(),userDao.getUserGrantedAuthoritys(user.getId()));
    }
}

自定義的方式只要實(shí)現(xiàn)接口方法loadUserByUsername(String username)即可,返回代表用戶的UserDetails對(duì)象。調(diào)用方式也很簡(jiǎn)單:

    /**
     * 配置user-detail服務(wù)
     * @param auth
     * @throws Exception
     */
    @Override
    public void configure(AuthenticationManagerBuilder auth)throws Exception{
        //自定義方式
        auth.userDetailsService(securityUserDetailsService);
    }

基于xml方式:

    <security:authentication-manager>
        <security:authentication-provider user-service-ref="blogUserDetailService">
        </security:authentication-provider>
    </security:authentication-manager>

4、密碼加密策略

通常我們?cè)诖鎯?chǔ)密碼的時(shí)候都是進(jìn)行加密的,spring security默認(rèn)提供了三種密碼存儲(chǔ)方式,同時(shí)也可以使用自定義的加密方式:

  • NoOpPasswordEncoder 明文方式保存
  • BCtPasswordEncoder 強(qiáng)hash方式加密
  • StandardPasswordEncoder SHA-256方式加密
  • 實(shí)現(xiàn)PasswordEncoder接口 自定義加密方式
    注解編碼方式:
    /**
     * 配置user-detail服務(wù)
     * @param auth
     * @throws Exception
     */
    @Override
    public void configure(AuthenticationManagerBuilder auth)throws Exception{
        //基于數(shù)據(jù)庫(kù)的用戶存儲(chǔ)、認(rèn)證
        auth.jdbcAuthentication().dataSource(dataSource)
                .usersByUsernameQuery("select account,password,true from user where account=?")
                .authoritiesByUsernameQuery("select account,role from user where account=?")
                .passwordEncoder(NoOpPasswordEncoder.getInstance());
    }

通過(guò)方法passwordEncoder傳入對(duì)應(yīng)的加密實(shí)例即可。

xml配置方式:

<security:authentication-manager>
        <security:authentication-provider>
            <security:jdbc-user-service data-source-ref="dataSource"
                                        authorities-by-username-query="select account,role from user where account=?"
                                        users-by-username-query="select account,password,true from user where account=?"/>
            <security:password-encoder ref="bcryptEncoder"/>
        </security:authentication-provider>
    </security:authentication-manager>

    <bean id="bcryptEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"/>

5、請(qǐng)求攔截策略

下面開始介紹一下spring security的重要功能,請(qǐng)求攔截策略。spring security的請(qǐng)求攔截匹配有兩種風(fēng)格,ant風(fēng)格和正則表達(dá)式風(fēng)格。編碼方式是通過(guò)重載configure(HttpSecurity)方法實(shí)現(xiàn)。

    /**
     * 攔截請(qǐng)求
     * @param http
     * @throws Exception
     */
    @Override
    public void configure(HttpSecurity http)throws Exception{
        http.authorizeRequests()
                .antMatchers("/","/css/**","/js/**").permitAll()   //任何人都可以訪問(wèn)
                .antMatchers("/admin/**").access("hasRole('ADMIN')")     //持有user權(quán)限的用戶可以訪問(wèn)
                .antMatchers("/user/**").hasAuthority("ROLE_USER");
    }

上面使用的是ant風(fēng)格的匹配,可以通過(guò)http.regexMatcher()方法使用正則表達(dá)式風(fēng)格。

對(duì)應(yīng)的xml配置方式:

    <security:http auto-config="true" use-expressions="true">
        <security:intercept-url pattern="/admin/*" access="hasRole('ROLE_ADMIN')"/>
        <security:intercept-url pattern="/user/*" access="hasRole('ROLE_USER')"/>
    </security:http>

除了上面的請(qǐng)求保護(hù)方法外,還有一些方法能夠用來(lái)定義如何保護(hù)請(qǐng)求。

access(String)     如果給定的SpEL表達(dá)式計(jì)算結(jié)果為true,就允許訪問(wèn)
anonymous()        允許匿名用戶訪問(wèn)
authenticated()    允許認(rèn)證過(guò)的用戶訪問(wèn)
denyAll()          無(wú)條件拒絕所有訪問(wèn)
fullyAuthenticated()   如果用戶是完整認(rèn)證的話(不是通過(guò)Remember-me功能認(rèn)證的),就允許訪問(wèn)
hasAnyAuthority(String...)   如果用戶具備給定權(quán)限中的某一個(gè)的話,就允許訪問(wèn)
hasAnyRole(String...)   如果用戶具備給定角色中的某一個(gè)的話,就允許訪問(wèn)
hasAuthority(String)   如果用戶具備給定權(quán)限的話,就允許訪問(wèn)
hasIpAddress(String)   如果請(qǐng)求來(lái)自給定IP地址的話,就允許訪問(wèn)
hasRole(String)   如果用戶具備給定角色的話,就允許訪問(wèn)
not()   對(duì)其他訪問(wèn)方法的結(jié)果求反
permitAll()   無(wú)條件允許訪問(wèn)
rememberMe()   如果用戶是通過(guò)Remember-me功能認(rèn)證的,就允許訪問(wèn)

6、強(qiáng)制安全性通道

通常我們都是使用http發(fā)送數(shù)據(jù),這種方式是不安全的。對(duì)于敏感信息我們通常都是通過(guò)https進(jìn)行加密發(fā)送。spring security對(duì)于安全性通道也提供了一種方式。我們可以在配置中添加requiresChannel()方法使url強(qiáng)制使用https。

    /**
     * 攔截請(qǐng)求
     * @param http
     * @throws Exception
     */
    @Override
    public void configure(HttpSecurity http)throws Exception{
        http.authorizeRequests()
                .antMatchers("/","/css/**","/js/**").permitAll()   //任何人都可以訪問(wèn)
                .antMatchers("/admin/**").access("hasRole('ADMIN')")     //持有user權(quán)限的用戶可以訪問(wèn)
                .antMatchers("/user/**").hasAuthority("ROLE_USER")
                .and()
                .requiresChannel().antMatchers("/admin/info").requiresSecure();
    }

不論何時(shí),只要是對(duì)“/admin/info”的請(qǐng)求,spring security都認(rèn)為需要安全性通道,并自動(dòng)將請(qǐng)求重定向到https上。

與之相反,如果有些請(qǐng)求不需要https傳送,可以使用requiresInsecure()替代requiresSecure(),將請(qǐng)求聲明為始終使用http傳送。

對(duì)應(yīng)xml配置:

    <security:http auto-config="true" use-expressions="true">
        <security:intercept-url pattern="/admin/*" access="hasRole('ROLE_ADMIN')"/>
        <security:intercept-url pattern="/user/*" access="hasRole('ROLE_USER')" />
        <security:intercept-url pattern="/admin/info" access="hasRole('ROLE_ADMIN')" requires-channel="https"/>
    </security:http>

7、防止CSRF

spring security從版本3.2開始,默認(rèn)就會(huì)啟用CSRF防護(hù)。spring security通過(guò)一個(gè)同步token的方式來(lái)實(shí)現(xiàn)CSRF防護(hù)功能。它會(huì)攔截狀態(tài)變化的請(qǐng)求,并檢查CSRF token。如果請(qǐng)求中不包含CSRF token的話,或者token不能與服務(wù)器端的token匹配,請(qǐng)求就會(huì)失敗,并拋出CsrfException異常。

如果使用JSP作為頁(yè)面模板的話,需要作的非常簡(jiǎn)單。

<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>

這樣就spring security就會(huì)自動(dòng)生成csrf token。如果想關(guān)閉csrf防護(hù),需要作的也很簡(jiǎn)單,只需要調(diào)用一下csrf().disable();即可。

編碼方式:

    /**
     * 攔截請(qǐng)求
     * @param http
     * @throws Exception
     */
    @Override
    public void configure(HttpSecurity http)throws Exception{
        http.authorizeRequests()
                .antMatchers("/","/css/**","/js/**").permitAll()   //任何人都可以訪問(wèn)
                .antMatchers("/admin/**").access("hasRole('ADMIN')")     //持有user權(quán)限的用戶可以訪問(wèn)
                .antMatchers("/user/**").hasAuthority("ROLE_USER")
                .and().csrf().disable();
    }

對(duì)應(yīng)xml方式:

    <security:http auto-config="true" use-expressions="true">
        <security:csrf disabled="true" />
        <security:intercept-url pattern="/admin/*" access="hasRole('ROLE_ADMIN')"/>
        <security:intercept-url pattern="/user/*" access="hasRole('ROLE_USER')" />
    </security:http>

8、remember-me功能

remember-me是一個(gè)很重要的功能,用戶肯定不希望每次都輸入用戶名密碼進(jìn)行登錄。spring security提供的remember-me功能使用起來(lái)非常簡(jiǎn)單。啟用這個(gè)功能只需要調(diào)用rememberMe()方法即可。

    /**
     * 攔截請(qǐng)求
     * @param http
     * @throws Exception
     */
    @Override
    public void configure(HttpSecurity http)throws Exception{
        http.authorizeRequests()
                .antMatchers("/","/css/**","/js/**").permitAll()   //任何人都可以訪問(wèn)
                .antMatchers("/admin/**").access("hasRole('ADMIN')")     //持有user權(quán)限的用戶可以訪問(wèn)
                .antMatchers("/user/**").hasAuthority("ROLE_USER")
                .and().rememberMe().key("abc").rememberMeParameter("remember_me").rememberMeCookieName("my-remember-me").tokenValiditySeconds(86400);
    }

同時(shí)可以設(shè)置參數(shù)名稱,cookie的name和過(guò)期時(shí)間。對(duì)應(yīng)的xml配置:

    <security:http auto-config="true" use-expressions="true">
        <security:remember-me />
        <security:intercept-url pattern="/admin/*" access="hasRole('ROLE_ADMIN')"/>
        <security:intercept-url pattern="/user/*" access="hasRole('ROLE_USER')" />
    </security:http>

remember-me有多種參數(shù)可以選擇配置。

這里有個(gè)需要注意的地方 ,在登錄頁(yè)面內(nèi)的remember-me的input標(biāo)簽內(nèi)不要設(shè)置value的值,否則remember-me功能將不會(huì)生效。

9、自定義登錄頁(yè)面

spring security會(huì)提供一個(gè)默認(rèn)的登錄頁(yè)面,如果你想使用自己的登錄頁(yè)面,可以這樣設(shè)置。

編碼方式:

    /**
     * 攔截請(qǐng)求
     * @param http
     * @throws Exception
     */
    @Override
    public void configure(HttpSecurity http)throws Exception{
        http.authorizeRequests()
                .antMatchers("/","/css/**","/js/**").permitAll()   //任何人都可以訪問(wèn)
                .antMatchers("/admin/**").access("hasRole('ADMIN')")     //持有user權(quán)限的用戶可以訪問(wèn)
                .antMatchers("/user/**").hasAuthority("ROLE_USER")
                .and().formLogin()
                .loginPage("/login").usernameParameter("username").passwordParameter("password")
                .and().exceptionHandling().accessDeniedPage("/loginfail");
    }

通過(guò)formLogin()方法來(lái)設(shè)置使用自定義登錄頁(yè)面,loginPage是登錄頁(yè)面地址,accessDeniePage登錄失敗跳轉(zhuǎn)地址。

對(duì)應(yīng)的xml配置:

    <security:http auto-config="true" use-expressions="true">
        <security:intercept-url pattern="/admin/*" access="hasRole('ROLE_ADMIN')"/>
        <security:intercept-url pattern="/user/*" access="hasRole('ROLE_USER')" />
        <security:form-login login-page="/login"
                             username-parameter="username"
                             password-parameter="password"
                             authentication-failure-url="/loginfail"
                             default-target-url="/"/>
    </security:http>

到此spring security的一些常用功能就介紹完了,寫的比較粗糙,可能會(huì)存在一些錯(cuò)誤。歡迎大家反饋交流。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容