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等语言最新前言技术,及业务痛点问题分析,请关注【编程我最懂】共同交流学习。


分享到:


相關文章: