01.05 Spring Cloud Security集成CAS實現微服務(單點登錄)

目錄

Spring Security介紹

Spring Security認證流程

Demo

  • 自定義登錄頁與退出
  • 從數據庫中驗證用戶
  • 密碼加密

CAS單點登錄系統

  • 先說單點登錄是何物?
  • 再來說說CAS又是何物?

CAS服務端部署

  • CAS認證

CAS客戶端過濾器配置文件web.xml

  • CAS客戶端與Spring Security集成

Spring Security介紹

Spring Security是一個能夠為基於Spring的企業應用系統提供聲明式的安全訪問控制解決方案的安全框架。它提供了一組可以在Spring應用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反轉Inversion of Control ,DI:Dependency Injection 依賴注入)和AOP(面向切面編程)功能,為應用系統提供聲明式的安全訪問控制功能,減少了為企業系統安全控制編寫大量重複代碼的工作。

Spring Security認證流程

  1. 用戶使用用戶名和密碼進行登錄。
  2. Spring Security 將獲取到的用戶名和密碼封裝成一個實現了 Authentication 接口的 UsernamePasswordAuthenticationToken。
  3. 將上述產生的 token 對象傳遞給 AuthenticationManager 進行登錄認證。
  4. AuthenticationManager 認證成功後將會返回一個封裝了用戶權限等信息的 Authentication 對象。
  5. 通過調用 SecurityContextHolder.getContext().setAuthentication(...) 將 AuthenticationManager 返回的 Authentication 對象賦予給當前的 SecurityContext。
Spring Cloud Security集成CAS實現微服務(單點登錄)

下面對上面提到的類進行簡單的介紹

Authentication:認證用戶信息的接口,用戶登錄認證之前之後有不同的實現類。認證成功之後保存在SecurityContextHolder持有的SecurityContext中。

SecurityContextHolder:使用ThreadLocal來保存SecurityContext。為了保證安全,在每一次request結束後都將清除當前線程ThreadLocal。

AuthenticationManager:處理認證(Authentication)請求的接口。只有一個authenticate()方法,接收一個代表認證請求的Authentication對象作為參數,認證成功則返回一個封裝了當前用戶權限等信息的Authentication對象進行返回。AuthenticationManager委託其配置的AuthenticationProvider列表處理認證請求,每一個AuthenticationProvider依次進行認證,只要有一個AuthenticationProvider 認證後的結果不為null,則表示該AuthenticationProvider已經認證成功,之後的AuthenticationProvider將不再繼續認證。如果所有的AuthenticationProvider的認證結果都為null,則表示認證失敗,將拋出一個ProviderNotFoundException。

Demo

自定義登錄頁與退出

添加依賴

<code><dependencies> 


<dependency>
\t<groupid>org.springframework.security/<groupid>
\t<artifactid>spring-security-web/<artifactid>
\t<version>{spring-security-version}/<version>
/<dependency>
<dependency>
\t<groupid>org.springframework.security/<groupid>
\t<artifactid>spring-security-config/<artifactid>
\t<version>{spring-security-version}/<version>
/<dependency>
/<dependencies>/<code>

XML配置方式

初始配置文件web.xml

<code>
<web-app>\txmlns="http://java.sun.com/xml/ns/javaee"
\txsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
\tversion="2.5">\t
\t <context-param>
\t\t<param-name>contextConfigLocation/<param-name>
\t\t<param-value>classpath:spring-security.xml/<param-value>
\t /<context-param>
\t <listener>
\t\t<listener-class>
\t\t\torg.springframework.web.context.ContextLoaderListener
\t\t/<listener-class>
\t /<listener>

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

Spring Security配置文件spring-security.xml

<code>
<beans>\txmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
\txsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
\t\t\t\t\t\thttp://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">

\t
\t<http>
\t<http>
\t
\t<http>
\t\t
\t\t<intercept-url>
\t\t
\t\t<form-login>

\t\t<csrf>

<logout>
\t/<http>
\t
\t<authentication-manager>
\t\t<authentication-provider>
\t\t\t<user-service>
\t\t\t\t<user>
\t\t\t/<user-service>
\t\t/<authentication-provider>\t
\t/<authentication-manager>
/<beans>/<code>

註解方式

Spring配置類AppConfig.java,替代Spring的XML配置文件

<code>@EnableWebMvc
@Configuration
@ComponentScan({"com.springsecurity.*"})
public class AppConfig {
@Bean
public SpringResourceTemplateResolver springResourceTemplateResolver() {
SpringResourceTemplateResolver springResourceTemplateResolver = new SpringResourceTemplateResolver();
springResourceTemplateResolver.setPrefix("/WEB-INF/pages/");
springResourceTemplateResolver.setSuffix(".html");
springResourceTemplateResolver.setTemplateMode("HTML");
springResourceTemplateResolver.setCacheable(false);
springResourceTemplateResolver.setCharacterEncoding("UTF-8");
return springResourceTemplateResolver;
}
@Bean
public SpringTemplateEngine springTemplateEngine() {
SpringTemplateEngine springTemplateEngine = new SpringTemplateEngine();
springTemplateEngine.setTemplateResolver(springResourceTemplateResolver());
return springTemplateEngine;
}
@Bean
public ThymeleafViewResolver thymeleafViewResolver() {
ThymeleafViewResolver thymeleafViewResolver = new ThymeleafViewResolver();
thymeleafViewResolver.setTemplateEngine(springTemplateEngine());
thymeleafViewResolver.setCharacterEncoding("UTF-8");
return thymeleafViewResolver;
}
}/<code>

Spring Security配置類SecurityConfig.java,替代Spring Security的XML配置文件spring-security.xml

<code>@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

\t@Autowired
\tpublic void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
\t auth.inMemoryAuthentication().withUser("admin").password("123456").roles("USER");
\t}

\t@Override
\tprotected void configure(HttpSecurity http) throws Exception {
\t http.authorizeRequests()
\t\t.antMatchers("/**").access("hasRole('ROLE_USER')")
\t\t.and().formLogin().loginPage("/login.html");
\t\t

\t}
}/<code>

擴展類SpringSecurityInitializer.java繼承AbstractSecurityWebApplicationInitializer自動地加載SpringSecurityFilterChain,相當於在web.xml中配置spring security的filter

<code>public class SpringSecurityInitializer extends AbstractSecurityWebApplicationInitializer {
//do nothing
}/<code>

初始化加載類SpringMvcInitializer.java,替代web.xml文件

<code>public class SpringMvcInitializer 
extends AbstractAnnotationConfigDispatcherServletInitializer {

\t@Override
\tprotected Class>[] getRootConfigClasses() {
\t\treturn new Class[] { AppConfig.class };
\t}

\t@Override
\tprotected Class>[] getServletConfigClasses() {
\t\treturn null;
\t}

\t@Override
\tprotected String[] getServletMappings() {
\t\treturn new String[] { "/" };
\t}
\t
}/<code>

從數據庫中驗證用戶

再添加兩個依賴

<code><dependency>
<groupid>org.springframework/<groupid>
<artifactid>spring-jdbc/<artifactid>
<version>${spring.version}/<version>
/<dependency>
<dependency>
<groupid>mysql/<groupid>
<artifactid>mysql-connector-java/<artifactid>
<version>${mysql.connector.version}/<version>
/<dependency>/<code>

數據庫語句

<code>CREATE TABLE users (
username VARCHAR(20) NOT NULL ,
password VARCHAR(20) NOT NULL ,
enabled BOOLEAN DEFAULT TRUE NOT NULL,
PRIMARY KEY (username)
);
CREATE TABLE user_roles (
user_role_id int(11) NOT NULL AUTO_INCREMENT,
username varchar(20) NOT NULL,
role varchar(20) NOT NULL,
PRIMARY KEY (user_role_id),
UNIQUE KEY uni_username_role (role,username),
KEY fk_username_idx (username),
CONSTRAINT fk_username FOREIGN KEY (username) REFERENCES users (username)
);/<code>

XML方式

數據庫配置文件spring-database.xml

<code>
<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.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">
<bean>
<property>
<property>
<property>
<property>
/<bean>
/<beans>/<code>

修改spring-security.xml配置文件:

<code>
<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">

<http>

<intercept-url>

<access-denied-handler>
<form-login> login-page="/login"
default-target-url="/welcome"
authentication-failure-url="/login?error"
username-parameter="user-name"
password-parameter="pwd"/>
<logout> logout-success-url="/login?logout"/>
<csrf>
/<logout>/<form-login>/<http>
<authentication-manager>
<authentication-provider>
<jdbc-user-service> users-by-username-query="select username,password, enabled from users where username = ?"
authorities-by-username-query="select username, role from user_roles where username = ?"/>
/<jdbc-user-service>/<authentication-provider>
/<authentication-manager>
/<beans>/<code>

在web.xml中添加對數據庫配置文件的指定

<code><context-param>
<param-name>contextConfigLocation/<param-name>
<param-value>
/WEB-INF/spring-security.xml
/WEB-INF/spring-database.xml
/<param-value>
/<context-param>/<code>

註解方式

把數據庫配置文件改為在配置類AppConfig中配置,添加以下代碼

<code>@EnableWebMvc
@Configuration
@ComponentScan({"com.springsecurity.*"})
public class AppConfig {
@Bean
public SpringResourceTemplateResolver springResourceTemplateResolver() {
SpringResourceTemplateResolver springResourceTemplateResolver = new SpringResourceTemplateResolver();
springResourceTemplateResolver.setPrefix("/WEB-INF/pages/");
springResourceTemplateResolver.setSuffix(".html");
springResourceTemplateResolver.setTemplateMode("HTML");

springResourceTemplateResolver.setCacheable(false);
springResourceTemplateResolver.setCharacterEncoding("UTF-8");
return springResourceTemplateResolver;
}

@Bean(name = "dataSource")
public DriverManagerDataSource dataSource() {
DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource();
driverManagerDataSource.setDriverClassName("com.mysql.jdbc.Driver");
driverManagerDataSource.setUrl("jdbc:mysql://127.0.0.1:3306/security");
driverManagerDataSource.setUsername("root");
driverManagerDataSource.setPassword("root");
return driverManagerDataSource;
}

@Bean
public SpringTemplateEngine springTemplateEngine() {
SpringTemplateEngine springTemplateEngine = new SpringTemplateEngine();
springTemplateEngine.setTemplateResolver(springResourceTemplateResolver());
springTemplateEngine.addDialect(new SpringSecurityDialect());
return springTemplateEngine;
}

@Bean
public ThymeleafViewResolver thymeleafViewResolver() {
ThymeleafViewResolver thymeleafViewResolver = new ThymeleafViewResolver();
thymeleafViewResolver.setTemplateEngine(springTemplateEngine());
thymeleafViewResolver.setCharacterEncoding("UTF-8");
return thymeleafViewResolver;
}
}/<code>

修改SecurityConfig.java

<code>@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Resource
private DataSource dataSource;

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(dataSource)
.usersByUsernameQuery("select username,password, enabled from users where username = ?")
.authoritiesByUsernameQuery("select username, role from user_roles where username = ?");
}

\t@Autowired
\tpublic void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {

\t auth.inMemoryAuthentication().withUser("admin").password("123456").roles("USER");
\t}

\t@Override
\tprotected void configure(HttpSecurity http) throws Exception {

\t http.authorizeRequests()
\t\t.antMatchers("/**").access("hasRole('ROLE_USER')")
\t\t.and().formLogin().loginPage("/login.html");
\t\t
\t}
}/<code>

密碼加密

XML方式

修改spring-security.xml配置文件,創建和注入PasswordEncoder到 AuthenticationProvider並設置作為身份驗證提供者在AuthenticationManagerBuilder

<code>
<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">

<http>
<intercept-url>

<access-denied-handler>
<form-login> login-page="/login"
default-target-url="/welcome"
authentication-failure-url="/login?error"
username-parameter="user-name"
password-parameter="pwd"/>
<logout> logout-success-url="/login?logout"/>
<csrf>
/<logout>/<form-login>/<http>
<authentication-manager>
<authentication-provider>
<password-encoder>
/<authentication-provider>
/<authentication-manager>


<bean>

<bean>
/<beans>/<code>

註解方式

修改SecurityConfig.java

<code>@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Resource
private DataSource dataSource;

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(dataSource)
.usersByUsernameQuery("select username,password, enabled from users where username = ?")
.authoritiesByUsernameQuery("select username, role from user_roles where username = ?");
}

\t@Autowired
\tpublic void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
\t auth.inMemoryAuthentication().withUser("admin").password("123456").roles("USER");
\t}

@Autowired
\t@Qualifier("customUserDetailsService")
\tUserDetailsService userDetailsService;
\t
\t
\t@Autowired
\tpublic void configureGlobalSecurity(AuthenticationManagerBuilder auth) throws Exception {
\t\tauth.userDetailsService(userDetailsService);
\t\tauth.authenticationProvider(authenticationProvider());
\t}
\t
\t
\t@Bean
\tpublic PasswordEncoder passwordEncoder() {
\t return new BCryptPasswordEncoder();
\t}
\t
\t
\t@Bean

\tpublic DaoAuthenticationProvider authenticationProvider() {
\t DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
\t authenticationProvider.setUserDetailsService(userDetailsService);
\t authenticationProvider.setPasswordEncoder(passwordEncoder());
\t return authenticationProvider;
\t}


\t@Override
\tprotected void configure(HttpSecurity http) throws Exception {

\t http.authorizeRequests()
\t\t.antMatchers("/**").access("hasRole('ROLE_USER')")
\t\t.and().formLogin().loginPage("/login.html");
\t\t
\t}
}/<code>

邏輯層實現在保存新的口令到數據庫中之前進行密碼編碼加密

<code>@Service("userService")
@Transactional
public class UserServiceImpl implements UserService{

\t@Autowired
\tprivate UserDao dao;
\t
\t@Autowired
\tprivate PasswordEncoder passwordEncoder;

\t
\tpublic void save(User user){
\t\tuser.setPassword(passwordEncoder.encode(user.getPassword()));
\t\tdao.save(user);
\t}
\t
\tpublic User findById(int id) {
\t\treturn dao.findById(id);
\t}

\tpublic User findBySso(String sso) {
\t\treturn dao.findBySSO(sso);
\t}
\t
}/<code>

CAS單點登錄系統

先說單點登錄是何物?

單點登錄(Single Sign On),目前比較流行的企業業務整合解決方案之一。在多數大型系統中也能見到,如天貓、京東。作用就是用戶在系統中登錄一次就可以訪問所有相互信任的應用系統。而這一點session是無法做到的。

再來說說CAS又是何物?

簡單來說,cas就是單點登錄的一種實現,由耶魯大學發起的開源項目,旨在為 Web 應用系統提供一種可靠的單點登錄方法。

CAS 包含兩個部分: CAS Server 和 CAS Client。CAS Server負責對用戶的認證工作;CAS Client負責處理對客戶端受保護資源的訪問請求,需要登錄時,重定向到 CAS Server。

CAS服務端部署

1、從官網http://developer.jasig.org/cas/下載服務器壓縮包並解壓

2、將解壓目錄cas-server-4.0.0-release\\cas-server-4.0.0\\modules路徑下的cas-server-webapp-4.0.0.war包拷貝到Tomcat服務器webapps的目錄下,可重命名為更簡單的名稱,如:cas.war。

3、啟動Tomcat訪問http://localhost:8080/cas即可看到cas首頁

CAS認證

CAS默認使用的是HTTPS協議,如果使用HTTPS協議需要SSL安全證書(需向特定的機構申請和購買),我們在本地機器可生成供本地使用的證書,如下:

生成證書的命令參數介紹

-genkeypair 生成密鑰-keyalg 指定密鑰算法

-keysize 指定密鑰長度,默認是1024位

-siglag 指定數字簽名算法

-validity 指定證書有效期,以天為單位

-alias 指定別名

-storepass 指定密碼

-keystore 指定密鑰庫存儲位置

-dname 指定用戶信息

1、打開JDK安裝目錄\\bin路徑下的keytool.exe

<code>keytool -genkeypair -alias cas -keyalg RSA -storepass changeit/<code>

在用戶目錄生成.keystore文件,刪除的命令為

<code>keytool -delete -alias  -storepass /<code>

查看的命令為

<code>keytool -list -storepass /<code>

2、導出證書

<code>keytool -exportcert -alias  -file  -storepass /<code>

3、導入證書到JVM

<code>keytool -importcert -alias cas-file cas.crt -keystore "%JAVA_HOME%\\jre\\lib\\security\\cacerts" -storepass changeit –noprompt/<code>

4、修改Tomcat配置文件server.xml以支持https協議

(1)將

<code>/<code>

去掉註釋修改為

<code><connector>               maxThreads="150" scheme="https" secure="true"  
clientAuth="false" sslProtocol="TLS"
keystoreFile=""
keystorePass="" /> /<connector>/<code>

(2)將

<code>
<listener>/<code>

改為

<code>
<listener>/<code>

5、啟動Tomcat訪問https://localhost:8443/cas

如果覺得以上安裝證書太麻煩,開發測試階段也可以直接去掉https安全認證,使用http協議

(1)修改cas的WEB-INF/deployerConfigContext.xml文件

<code><bean>          class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler"
p:httpClient-ref="httpClient"/>/<bean>/<code>

改為

<code><bean>          class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler"
p:httpClient-ref="httpClient" p:requireSecure="false"/>/<bean>/<code>

(2)修改cas的/WEB-INF/spring-configuration/ticketGrantingTicketCookieGenerator.xml文件

<code><bean>      p:cookieSecure="true"
p:cookieMaxAge="-1"
p:cookieName="CASTGC"
p:cookiePath="/cas" />/<bean>/<code>

改為

<code><bean>      p:cookieSecure="false"
p:cookieMaxAge="3600"
p:cookieName="CASTGC"
p:cookiePath="/cas" />/<bean>/<code>

(3)修改cas的WEB-INF/spring-configuration/warnCookieGenerator.xml文件,修改的東西與第(2)步一樣

CAS客戶端過濾器配置文件web.xml

<code>
<web-app>\txmlns="http://java.sun.com/xml/ns/javaee"
\txsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
\tversion="2.5">\t
\t
\t

<listener>
<listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener/<listener-class>

/<listener>


<filter>
<filter-name>CAS Single Sign Out Filter/<filter-name>
<filter-class>org.jasig.cas.client.session.SingleSignOutFilter/<filter-class>
/<filter>
<filter-mapping>
<filter-name>CAS Single Sign Out Filter/<filter-name>
<url-pattern>/*/<url-pattern>
/<filter-mapping>


<filter>
<filter-name>CASFilter/<filter-name>
<filter-class>org.jasig.cas.client.authentication.AuthenticationFilter/<filter-class>
<init-param>
<param-name>casServerLoginUrl/<param-name>
<param-value>http://localhost:8080/cas/login/<param-value>

/<init-param>
<init-param>
<param-name>serverName/<param-name>
<param-value>http://localhost:8080/<param-value>
/<init-param>
/<filter>
<filter-mapping>
<filter-name>CASFilter/<filter-name>
<url-pattern>/*/<url-pattern>
/<filter-mapping>


<filter>
<filter-name>CAS Validation Filter/<filter-name>
<filter-class>
org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter/<filter-class>
<init-param>
<param-name>casServerUrlPrefix/<param-name>
<param-value>http://localhost:8080/cas/<param-value>
/<init-param>

<init-param>
<param-name>serverName/<param-name>
<param-value>http://localhost:8080/<param-value>
/<init-param>
/<filter>
<filter-mapping>
<filter-name>CAS Validation Filter/<filter-name>
<url-pattern>/*/<url-pattern>
/<filter-mapping>


<filter>
<filter-name>CAS HttpServletRequest Wrapper Filter/<filter-name>
<filter-class>
org.jasig.cas.client.util.HttpServletRequestWrapperFilter/<filter-class>
/<filter>
<filter-mapping>
<filter-name>CAS HttpServletRequest Wrapper Filter/<filter-name>
<url-pattern>/*/<url-pattern>
/<filter-mapping>


<filter>
<filter-name>CAS Assertion Thread Local Filter/<filter-name>
<filter-class>org.jasig.cas.client.util.AssertionThreadLocalFilter/<filter-class>
/<filter>
<filter-mapping>
<filter-name>CAS Assertion Thread Local Filter/<filter-name>
<url-pattern>/*/<url-pattern>
/<filter-mapping>


/<web-app>/<code>

CAS客戶端與Spring Security集成

Spring Security通過spring-security-cas插件集成對CAS的封裝,可以將上面CAS客戶端一系列的配置以bean的形式嫁接到Spring Security的配置文件中,也就是Spring的依賴注入。

示例:

添加依賴

<code><dependencies>
\t\t<dependency>
\t\t\t<groupid>org.springframework/<groupid>
\t\t\t<artifactid>spring-core/<artifactid>
\t\t\t<version>${spring.version}/<version>
\t\t/<dependency>
\t\t<dependency>
\t\t\t<groupid>org.springframework/<groupid>
\t\t\t<artifactid>spring-web/<artifactid>
\t\t\t<version>${spring.version}/<version>
\t\t/<dependency>
\t\t<dependency>
\t\t\t<groupid>org.springframework/<groupid>
\t\t\t<artifactid>spring-webmvc/<artifactid>
\t\t\t<version>${spring.version}/<version>
\t\t/<dependency>
\t\t<dependency>
\t\t\t<groupid>org.springframework/<groupid>
\t\t\t<artifactid>spring-context-support/<artifactid>
\t\t\t<version>${spring.version}/<version>
\t\t/<dependency>
\t\t<dependency>
\t\t\t<groupid>org.springframework/<groupid>
\t\t\t<artifactid>spring-test/<artifactid>
\t\t\t<version>${spring.version}/<version>
\t\t/<dependency>
\t\t<dependency>
\t\t\t<groupid>org.springframework/<groupid>
\t\t\t<artifactid>spring-jdbc/<artifactid>
\t\t\t<version>${spring.version}/<version>
\t\t/<dependency>
\t\t<dependency>
\t\t\t<groupid>javax.servlet/<groupid>
\t\t\t<artifactid>servlet-api/<artifactid>
\t\t\t<version>2.5/<version>
\t\t\t<scope>provided/<scope>
\t\t/<dependency>
\t\t<dependency>
\t\t\t<groupid>org.springframework.security/<groupid>
\t\t\t<artifactid>spring-security-web/<artifactid>
\t\t\t<version>4.1.0.RELEASE/<version>
\t\t/<dependency>
\t\t<dependency>

\t\t\t<groupid>org.springframework.security/<groupid>
\t\t\t<artifactid>spring-security-config/<artifactid>
\t\t\t<version>4.1.0.RELEASE/<version>
\t\t/<dependency>
\t\t<dependency>
\t\t\t<groupid>org.springframework.security/<groupid>
\t\t\t<artifactid>spring-security-cas/<artifactid>
\t\t\t<version>4.1.0.RELEASE/<version>
\t\t/<dependency>
\t\t<dependency>
\t\t\t<groupid>org.jasig.cas.client/<groupid>
\t\t\t<artifactid>cas-client-core/<artifactid>
\t\t\t<version>3.3.3/<version>
\t\t\t<exclusions>
\t\t\t\t<exclusion>
\t\t\t\t\t<groupid>org.slf4j/<groupid>
\t\t\t\t\t<artifactid>log4j-over-slf4j/<artifactid>
\t\t\t\t/<exclusion>
\t\t\t/<exclusions>
\t\t/<dependency>
\t/<dependencies>/<code>

初始配置文件web.xml

<code>
<web-app>\txmlns="http://java.sun.com/xml/ns/javaee"
\txsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
\tversion="2.5">\t
\t <context-param>
\t\t<param-name>contextConfigLocation/<param-name>
\t\t<param-value>classpath:spring-security.xml/<param-value>
\t /<context-param>
\t <listener>
\t\t<listener-class>
\t\t\torg.springframework.web.context.ContextLoaderListener
\t\t/<listener-class>
\t /<listener>
\t <filter>
\t\t<filter-name>springSecurityFilterChain/<filter-name>
\t\t<filter-class>org.springframework.web.filter.DelegatingFilterProxy/<filter-class>
\t /<filter>
\t <filter-mapping>
\t\t<filter-name>springSecurityFilterChain/<filter-name>
\t\t<url-pattern>/*/<url-pattern>
\t /<filter-mapping>
\t<servlet>
\t<servlet-name>springmvc/<servlet-name>
\t<servlet-class>org.springframework.web.servlet.DispatcherServlet/<servlet-class>
\t

\t\t<init-param>
\t\t<param-name>contextConfigLocation/<param-name>
\t\t<param-value>classpath:springmvc.xml/<param-value>
\t\t/<init-param>
\t/<servlet>
\t<servlet-mapping>
\t\t<servlet-name>springmvc/<servlet-name>
\t\t<url-pattern>*.do/<url-pattern>
\t/<servlet-mapping>
/<web-app>/<code>

springmvc.xml

<code>
<beans>\txmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
\txmlns:context="http://www.springframework.org/schema/context"
\txmlns:dubbo="http://code.alibabatech.com/schema/dubbo" xmlns:mvc="http://www.springframework.org/schema/mvc"
\txsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

<component-scan>
\t<annotation-driven>\t
/<beans>/<code>

Spring Security配置文件spring-security.xml

<code>
<beans>\txmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
\txsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
\t\t\t\t\t\thttp://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd">
\t
\t<http>
\t
\t<http>
<intercept-url>
<csrf>

<custom-filter>
<custom-filter>
<custom-filter>
/<http>
\t
<bean>

<property>
<property>
/<bean>
<bean>

<property>
/<bean>


<bean>
<property>
/<bean>
\t\t
\t<authentication-manager>
\t\t<authentication-provider>
\t\t/<authentication-provider>
\t/<authentication-manager>
\t\t
\t<bean>
<property>
<bean>
<constructor-arg>
/<bean>
/<property>
<property>

<property>
<bean>
<constructor-arg>
/<bean>

/<property>
<property>
/<bean>
\t\t
\t<bean>
\t
\t
<bean>

<bean>
<constructor-arg>
<constructor-arg>
<bean>
/<constructor-arg>
<property>
/<bean>

/<beans>/<code>

認證類UserDetailServiceImpl.java,繼承UserDetailsService,實現對用戶角色權限的認證

<code>public class UserDetailServiceImpl implements UserDetailsService {
\t@Override
\tpublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
\t\tSystem.out.println("經過認證類:"+username);
\t\t
\t\tList<grantedauthority> authorities=new ArrayList();
\t\tauthorities.add(new SimpleGrantedAuthority("ROLE_USER"));
\t\t
\t\treturn new User(username,"",authorities);
\t}
}/<grantedauthority>/<code>

控制類UserController.java

<code>@RestController
public class UserController {

\t@RequestMapping("/findLoginUser")

\tpublic void findLoginUser(){
\t\t//當前登錄名
\t\tString name = SecurityContextHolder.getContext().getAuthentication().getName();
\t\tSystem.out.println("當前登錄名:"+name);
\t}
}/<code>

index.html

<code>



<title>首頁/<title>


Hello,spring security01!

/<code>

index2.html

<code>



<title>首頁/<title>


Hello,spring security02!你已退出!

/<code>

經過spring-security.xml文件的配置,從index.html退出後會跳轉到index2.html頁面,index2.html不在攔截列表。


專注於技術熱點大數據,人工智能,JAVA、Python、 C 、GO、Javascript等語言最新前言技術,及業務痛點問題分析,請關注【編程我最懂】共同交流學習。


分享到:


相關文章: