5.1SpringSecurity搭建
5.1.1 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>com.itheima</groupId>
<artifactId>springsecurity-cas-annotation-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<!--war包-->
<packaging>war</packaging>
<dependencies>
<!--spring-security-->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<!--集成包-->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-cas</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<!--cas核心包-->
<dependency>
<groupId>org.jasig.cas.client</groupId>
<artifactId>cas-client-core</artifactId>
<version>3.3.3</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--日志包-->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<!--servlet-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
5.1.2 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!--指定spring配置文件-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml</param-value>
</context-param>
<!--spring監(jiān)聽-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--委托過濾器:springSecurityFilterChain-->
<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>
</web-app>
5.1.3 spring.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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--包掃描-->
<context:component-scan base-package="org.example" />
</beans>
5.1.4 創(chuàng)建自定義授權認證類
@Component
public class UserDetailsServiceImpl implements UserDetailsService {
/***
* 自定義認證授權
* @param username
* @return
* @throws UsernameNotFoundException
*/
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
String password="123456";
//角色信息
List<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();
grantedAuthorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));
return new User(username,password,grantedAuthorities);
}
}
5.1.5 創(chuàng)建SpringSecur配置類
配置類需要注意加上@Component淮菠、@EnableWebSecurity注解采郎,同時注解3個方法分別為忽略某些地址的安全校驗祟牲、設置需要攔截過濾的地址的安全校驗規(guī)則、設置授權認證器三個方法都是configure方法起意。代碼如下:
@Component
@EnableWebSecurity
public class SpringSecurityCOnfig extends WebSecurityConfigurerAdapter {
/***
* 三個configure方法
* 1)忽略某些地址的安全校驗
* 2)設置需要攔截過濾的地址的安全校驗規(guī)則
* 3)設置授權認證器
*/
/***
* 1)忽略某些地址的安全校驗
* @param web
* @throws Exception
*/
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/image/**");
web.ignoring().antMatchers("/403.html");
}
/***
* 2)設置需要攔截過濾的地址的安全校驗規(guī)則
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
//除了上面忽略安全校驗的地址,其他的一律需要ROLE_ADMIN角色權限訪問
http.authorizeRequests().anyRequest().access("hasAnyRole('ADMIN')");
//允許iframe的使用
http.headers().frameOptions().disable();
//禁止csrf
http.csrf().disable();
//開啟登錄功能
http.formLogin();
//開啟登出功能
http.logout();
//異常處理
http.exceptionHandling().accessDeniedPage("/403.html");
}
/***
* 注入自定義授權認證類
*/
@Autowired
private UserDetailsService userDetailsService;
/***
* 3)設置授權認證器
* @param auth
* @throws Exception
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
}
5.1.6 新建資源文件
創(chuàng)建image,并拷貝1.jpg進去病瞳,作為開放資源揽咕。創(chuàng)建jsp/1.jsp悲酷,作為權限控制目錄。創(chuàng)建403亲善,作為無權訪問的頁面设易。
5.2 集成CAS
5.2.1 創(chuàng)建cas.properties
這里面記錄了cas相關的訪問地址以及自身相關的訪問地址
#CAS服務地址
cas.server.host.url=http://localhost:28083/cas
#CAS服務登錄地址
cas.server.host.login_url=http://localhost:28083/cas/login
#CAS服務登出地址
cas.server.host.logout_url=http://localhost:28083/cas/logout?service=http://localhost:28086
#應用訪問地址
app.server.host.url=http://localhost:28086
#應用登錄地址
app.login.url=/login
#應用登出地址
app.logout.url=/logout
5.2.2 創(chuàng)建CasProperties.java配置類
該類的作用是用于讀取上面的配置文件
@Component
public class CasProperties {
@Value("${cas.server.host.url}")
private String casServerUrl;
@Value("${cas.server.host.login_url}")
private String casServerLoginUrl;
@Value("${cas.server.host.logout_url}")
private String casServerLogoutUrl;
@Value("${app.server.host.url}")
private String appServerUrl;
@Value("${app.login.url}")
private String appLoginUrl;
@Value("${app.logout.url}")
private String appLogoutUrl;
//get...set...
}
5.2.3 集成CAS認證和相關過濾器
修改configure方法,代碼如下蛹头,分別加入了自定義授權認證類和Cas過濾器以及登出配置顿肺。我們需要將之前的用戶自定義授權認證類去掉.
/***
* 2)設置需要攔截過濾的地址的安全校驗規(guī)則
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
//除了上面忽略安全校驗的地址,其他的一律需要ROLE_ADMIN角色權限訪問
http.authorizeRequests().anyRequest().access("hasAnyRole('ADMIN')");
//允許iframe的使用
http.headers().frameOptions().disable();
//禁止csrf
http.csrf().disable();
//開啟登錄功能
http.formLogin();
//開啟登出功能
http.logout();
//異常處理
http.exceptionHandling().accessDeniedPage("/403.html")
.authenticationEntryPoint(casAuthenticationEntryPoint()) //設置自定義授權認證類
.and()
.addFilter(casAuthenticationFilter()) //設置CAS授權過濾器
.addFilterBefore(casLogoutFilter(),LogoutFilter.class) //登出配置
.addFilterBefore(singleSignOutFilter(), CasAuthenticationFilter.class);//登出配置
}
過濾器以及授權認證類的實現(xiàn)
/***
* UserDetailsServiceImpl在SpringIOC容器中
*/
@Autowired
private UserDetailsService userDetailsService;
//Cas認證入口
@Bean
public CasAuthenticationEntryPoint casAuthenticationEntryPoint(){
//用于配置Cas認證入口信息
CasAuthenticationEntryPoint casAuthenticationEntryPoint = new CasAuthenticationEntryPoint();
//設置登錄地址
casAuthenticationEntryPoint.setLoginUrl(casProperties.getCasServerLoginUrl());
//返回的服務信息
casAuthenticationEntryPoint.setServiceProperties(serviceProperties());
return casAuthenticationEntryPoint;
}
/****
* 服務配置信息
* @return
*/
@Bean
public ServiceProperties serviceProperties(){
//服務信息配置
ServiceProperties serviceProperties = new ServiceProperties();
//設置應用訪問信息
serviceProperties.setService(casProperties.getAppServerUrl()+casProperties.getAppLoginUrl());
//針對非空登錄用戶進行身份校驗
serviceProperties.setAuthenticateAllArtifacts(true);
return serviceProperties;
}
/**CAS認證過濾器*/
@Bean
public CasAuthenticationFilter casAuthenticationFilter() throws Exception {
//設置CAS授權過濾器
CasAuthenticationFilter casAuthenticationFilter = new CasAuthenticationFilter();
//集成SpringSecurity授權認證器
casAuthenticationFilter.setAuthenticationManager(authenticationManager());
casAuthenticationFilter.setFilterProcessesUrl(casProperties.getAppLoginUrl());
return casAuthenticationFilter;
}
/**
* cas 認證 Provider
* */
@Bean
public CasAuthenticationProvider casAuthenticationProvider() {
//創(chuàng)建CAS授權認證器
CasAuthenticationProvider casAuthenticationProvider = new CasAuthenticationProvider();
//集成自定義授權認證器
casAuthenticationProvider.setUserDetailsService(userDetailsService);
//設置Cas授權認證器相關配置
casAuthenticationProvider.setServiceProperties(serviceProperties());
//設置票據(jù)校驗器
casAuthenticationProvider.setTicketValidator(cas20ServiceTicketValidator());
casAuthenticationProvider.setKey("casAuthenticationProviderKey");
return casAuthenticationProvider;
}
/**
* 設置票據(jù)校驗地址-CAS地址
* @return
*/
@Bean
public Cas20ServiceTicketValidator cas20ServiceTicketValidator() {
return new Cas20ServiceTicketValidator(casProperties.getCasServerUrl());
}
/**單點登出過濾器*/
@Bean
public SingleSignOutFilter singleSignOutFilter() {
SingleSignOutFilter singleSignOutFilter = new SingleSignOutFilter();
singleSignOutFilter.setCasServerUrlPrefix(casProperties.getCasServerUrl());
singleSignOutFilter.setIgnoreInitConfiguration(true);
return singleSignOutFilter;
}
/**請求單點退出過濾器*/
@Bean
public LogoutFilter casLogoutFilter() {
LogoutFilter logoutFilter = new LogoutFilter(casProperties.getCasServerLogoutUrl(), new SecurityContextLogoutHandler());
logoutFilter.setFilterProcessesUrl(casProperties.getAppLogoutUrl());
return logoutFilter;
}
5.2.4 完整代碼
@Component
@EnableWebSecurity //開啟SpringSecurity注解配置
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CasProperties casProperties;
//三個方法的方法名都是:configure
/***
* 1)忽略某些地址的安全校驗
* @param web
* @throws Exception
*/
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/image/**");
web.ignoring().antMatchers("/403.html");
}
/***
* 2)設置需要攔截過濾的地址的安全校驗規(guī)則
* @param http
* @throws Exception
*/
@Override
protected void configure(HttpSecurity http) throws Exception {
//除了上面忽略安全校驗的地址渣蜗,其他的一律需要ROLE_ADMIN角色權限訪問
http.authorizeRequests().anyRequest().access("hasAnyRole('ADMIN')");
//允許iframe的使用
http.headers().frameOptions().disable();
//禁止csrf
http.csrf().disable();
//開啟登錄功能
http.formLogin();
//開啟登出功能
http.logout();
//異常處理
http.exceptionHandling().accessDeniedPage("/403.html")
.authenticationEntryPoint(casAuthenticationEntryPoint()) //設置自定義授權認證類
.and()
.addFilter(casAuthenticationFilter()) //設置CAS授權過濾器
.addFilterBefore(casLogoutFilter(),LogoutFilter.class) //登出配置
.addFilterBefore(singleSignOutFilter(), CasAuthenticationFilter.class);//登出配置
}
/***
* UserDetailsServiceImpl在SpringIOC容器中
*/
@Autowired
private UserDetailsService userDetailsService;
//Cas認證入口
@Bean
public CasAuthenticationEntryPoint casAuthenticationEntryPoint(){
//用于配置Cas認證入口信息
CasAuthenticationEntryPoint casAuthenticationEntryPoint = new CasAuthenticationEntryPoint();
//設置登錄地址
casAuthenticationEntryPoint.setLoginUrl(casProperties.getCasServerLoginUrl());
//返回的服務信息
casAuthenticationEntryPoint.setServiceProperties(serviceProperties());
return casAuthenticationEntryPoint;
}
/****
* 服務配置信息
* @return
*/
@Bean
public ServiceProperties serviceProperties(){
//服務信息配置
ServiceProperties serviceProperties = new ServiceProperties();
//設置應用訪問信息
serviceProperties.setService(casProperties.getAppServerUrl()+casProperties.getAppLoginUrl());
//針對非空登錄用戶進行身份校驗
serviceProperties.setAuthenticateAllArtifacts(true);
return serviceProperties;
}
/**CAS認證過濾器*/
@Bean
public CasAuthenticationFilter casAuthenticationFilter() throws Exception {
//設置CAS授權過濾器
CasAuthenticationFilter casAuthenticationFilter = new CasAuthenticationFilter();
//集成SpringSecurity授權認證器
casAuthenticationFilter.setAuthenticationManager(authenticationManager());
casAuthenticationFilter.setFilterProcessesUrl(casProperties.getAppLoginUrl());
return casAuthenticationFilter;
}
/**
* cas 認證 Provider
* */
@Bean
public CasAuthenticationProvider casAuthenticationProvider() {
//創(chuàng)建CAS授權認證器
CasAuthenticationProvider casAuthenticationProvider = new CasAuthenticationProvider();
//集成自定義授權認證器
casAuthenticationProvider.setUserDetailsService(userDetailsService);
//設置Cas授權認證器相關配置
casAuthenticationProvider.setServiceProperties(serviceProperties());
//設置票據(jù)校驗器
casAuthenticationProvider.setTicketValidator(cas20ServiceTicketValidator());
casAuthenticationProvider.setKey("casAuthenticationProviderKey");
return casAuthenticationProvider;
}
/**
* 設置票據(jù)校驗地址-CAS地址
* @return
*/
@Bean
public Cas20ServiceTicketValidator cas20ServiceTicketValidator() {
return new Cas20ServiceTicketValidator(casProperties.getCasServerUrl());
}
/**單點登出過濾器*/
@Bean
public SingleSignOutFilter singleSignOutFilter() {
SingleSignOutFilter singleSignOutFilter = new SingleSignOutFilter();
singleSignOutFilter.setCasServerUrlPrefix(casProperties.getCasServerUrl());
singleSignOutFilter.setIgnoreInitConfiguration(true);
return singleSignOutFilter;
}
/**請求單點退出過濾器*/
@Bean
public LogoutFilter casLogoutFilter() {
LogoutFilter logoutFilter = new LogoutFilter(casProperties.getCasServerLogoutUrl(), new SecurityContextLogoutHandler());
logoutFilter.setFilterProcessesUrl(casProperties.getAppLogoutUrl());
return logoutFilter;
}
}