Spring BootはSpring securityを使ってCASを集積します。
1.プロジェクトの作成
Maven作成プロジェクト:springbook-security-cas
2.依存関係を追加
プロジェクトを作成した後、pom.xmlを開いて、pom.xmlに以下の内容を追加します。
appication.propertiesファイルを作成し、以下の内容を追加します。
入口起動類MainConfigを作成し、完全コードは以下の通りです。
Security配置類SecurityConfigを作成します。完全コードは以下の通りです。
(1)Cas Propertiesを定義し、propertiesファイルで指定された内容を注入して使いやすいようにします。ここに注入しなくてもいいです。Spring現在の環境を取得できます。コードは以下の通りです。
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。
Maven作成プロジェクト:springbook-security-cas
2.依存関係を追加
プロジェクトを作成した後、pom.xmlを開いて、pom.xmlに以下の内容を追加します。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.3.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- security starter Poms -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- security CAS -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-cas</artifactId>
</dependency>
<!-- security taglibs -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
</dependency>
<!-- -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
3.appication.propertiesを作成するappication.propertiesファイルを作成し、以下の内容を追加します。
#CAS
cas.server.host.url=http://localhost:8081/cas
#CAS
cas.server.host.login_url=${cas.server.host.url}/login
#CAS
cas.server.host.logout_url=${cas.server.host.url}/logout?service=${app.server.host.url}
#
app.server.host.url=http://localhost:8080
#
app.login.url=/login
#
app.logout.url=/logout
4.入り口起動類(MainConfig)の作成入口起動類MainConfigを作成し、完全コードは以下の通りです。
package com.chengli.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@SpringBootApplication
public class MainConfig {
public static void main(String[] args) {
SpringApplication.run(MainConfig.class, args);
}
@RequestMapping("/")
public String index() {
return " ";
}
@RequestMapping("/hello")
public String hello() {
return " ";
}
@PreAuthorize("hasAuthority('TEST')")// TEST
@RequestMapping("/security")
public String security() {
return "hello world security";
}
@PreAuthorize("hasAuthority('ADMIN')")// ADMIN
@RequestMapping("/authorize")
public String authorize() {
return " ";
}
/** ,TEST ADMIN , , */
}
5.Security配置類を作成する(SecurityConfig)Security配置類SecurityConfigを作成します。完全コードは以下の通りです。
package com.chengli.springboot.security;
import org.jasig.cas.client.session.SingleSignOutFilter;
import org.jasig.cas.client.validation.Cas20ServiceTicketValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.cas.ServiceProperties;
import org.springframework.security.cas.authentication.CasAssertionAuthenticationToken;
import org.springframework.security.cas.authentication.CasAuthenticationProvider;
import org.springframework.security.cas.web.CasAuthenticationEntryPoint;
import org.springframework.security.cas.web.CasAuthenticationFilter;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
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 org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
import org.springframework.security.web.authentication.logout.LogoutFilter;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import com.chengli.springboot.custom.CustomUserDetailsService;
import com.chengli.springboot.properties.CasProperties;
@Configuration
@EnableWebSecurity // web
@EnableGlobalMethodSecurity(prePostEnabled = true) //
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private CasProperties casProperties;
/** , */
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
super.configure(auth);
auth.authenticationProvider(casAuthenticationProvider());
//inMemoryAuthentication
//auth.inMemoryAuthentication().withUser("chengli").password("123456").roles("USER")
//.and().withUser("admin").password("123456").roles("ADMIN");
//jdbcAuthentication , security
//usersByUsernameQuery SQL
//authoritiesByUsernameQuery SQL
//auth.jdbcAuthentication().dataSource(dataSource).usersByUsernameQuery(query).authoritiesByUsernameQuery(query);
// userDetailsService, userDetailsService
//auth.userDetailsService(userDetailsService);
}
/** */
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()//
//.antMatchers("/","/hello").permitAll()// /
.anyRequest().authenticated()//
.and()
.logout()
.permitAll()// logout
.and()
.formLogin();// form
http.exceptionHandling().authenticationEntryPoint(casAuthenticationEntryPoint())
.and()
.addFilter(casAuthenticationFilter())
.addFilterBefore(casLogoutFilter(), LogoutFilter.class)
.addFilterBefore(singleSignOutFilter(), CasAuthenticationFilter.class);
//http.csrf().disable(); // CSRF
}
/** */
@Bean
public CasAuthenticationEntryPoint casAuthenticationEntryPoint() {
CasAuthenticationEntryPoint casAuthenticationEntryPoint = new CasAuthenticationEntryPoint();
casAuthenticationEntryPoint.setLoginUrl(casProperties.getCasServerLoginUrl());
casAuthenticationEntryPoint.setServiceProperties(serviceProperties());
return casAuthenticationEntryPoint;
}
/** service */
@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 {
CasAuthenticationFilter casAuthenticationFilter = new CasAuthenticationFilter();
casAuthenticationFilter.setAuthenticationManager(authenticationManager());
casAuthenticationFilter.setFilterProcessesUrl(casProperties.getAppLoginUrl());
return casAuthenticationFilter;
}
/**cas Provider*/
@Bean
public CasAuthenticationProvider casAuthenticationProvider() {
CasAuthenticationProvider casAuthenticationProvider = new CasAuthenticationProvider();
casAuthenticationProvider.setAuthenticationUserDetailsService(customUserDetailsService());
//casAuthenticationProvider.setUserDetailsService(customUserDetailsService()); // , , 。
casAuthenticationProvider.setServiceProperties(serviceProperties());
casAuthenticationProvider.setTicketValidator(cas20ServiceTicketValidator());
casAuthenticationProvider.setKey("casAuthenticationProviderKey");
return casAuthenticationProvider;
}
/*@Bean
public UserDetailsService customUserDetailsService(){
return new CustomUserDetailsService();
}*/
/** AuthenticationUserDetailsService*/
@Bean
public AuthenticationUserDetailsService<CasAssertionAuthenticationToken> customUserDetailsService(){
return new CustomUserDetailsService();
}
@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;
}
}
6.ユーザー定義クラス(1)Cas Propertiesを定義し、propertiesファイルで指定された内容を注入して使いやすいようにします。ここに注入しなくてもいいです。Spring現在の環境を取得できます。コードは以下の通りです。
package com.chengli.springboot.properties;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* CAS
* @author ChengLi
*/
@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;
...... getters setters
}
(2)CustoomUserDetails Service類を定義し、コードは以下の通りである。
package com.chengli.springboot.custom;
import java.util.HashSet;
import java.util.Set;
import org.springframework.security.cas.authentication.CasAssertionAuthenticationToken;
import org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
/**
* UserDetailsService , AuthenticationUserDetailsService
* @author ChengLi
*
*/
public class CustomUserDetailsService /*
// UserDetailsService , loadUserByUsername
implements UserDetailsService {
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
System.out.println(" :"+username);
// , ,
UserInfo userInfo = new UserInfo();
userInfo.setUsername("admin");
userInfo.setName("admin");
Set<AuthorityInfo> authorities = new HashSet<AuthorityInfo>();
AuthorityInfo authorityInfo = new AuthorityInfo("TEST");
authorities.add(authorityInfo);
userInfo.setAuthorities(authorities);
return userInfo;
}*/
// AuthenticationUserDetailsService, loadUserDetails
implements AuthenticationUserDetailsService<CasAssertionAuthenticationToken> {
@Override
public UserDetails loadUserDetails(CasAssertionAuthenticationToken token) throws UsernameNotFoundException {
System.out.println(" :"+token.getName());
/* , , */
UserInfo userInfo = new UserInfo();
userInfo.setUsername("admin");
userInfo.setName("admin");
Set<AuthorityInfo> authorities = new HashSet<AuthorityInfo>();
AuthorityInfo authorityInfo = new AuthorityInfo("TEST");
authorities.add(authorityInfo);
userInfo.setAuthorities(authorities);
return userInfo;
}
}
(3)AuthortyInfoクラスを定義し、現在ログインしているユーザの権限情報をロードするために、Granted Authortyインターフェースを実現します。コードは以下の通りです。
package com.chengli.springboot.custom;
import org.springframework.security.core.GrantedAuthority;
/**
*
*
* @author ChengLi
*
*/
public class AuthorityInfo implements GrantedAuthority {
private static final long serialVersionUID = -175781100474818800L;
/**
* CODE
*/
private String authority;
public AuthorityInfo(String authority) {
this.authority = authority;
}
@Override
public String getAuthority() {
return authority;
}
public void setAuthority(String authority) {
this.authority = authority;
}
}
(4)UserInfoクラスを定義し、現在のユーザ情報をロードするために、UserDetailsインターフェースを実現します。コードは以下の通りです。
package com.chengli.springboot.custom;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
/**
*
* @、 ,id,name,username,password,
* @author ChengLi
*
*/
public class UserInfo implements UserDetails {
private static final long serialVersionUID = -1041327031937199938L;
/**
* ID
*/
private Long id;
/**
*
*/
private String name;
/**
*
*/
private String username;
/**
*
*/
private String password;
private boolean isAccountNonExpired = true;
private boolean isAccountNonLocked = true;
private boolean isCredentialsNonExpired = true;
private boolean isEnabled = true;
private Set<AuthorityInfo> authorities = new HashSet<AuthorityInfo>();
.... getters setters
}
ここでは基本的に完了しました。CAS Serverを実行して、上記のaplication.propertiesファイルのアドレスを実際のアドレスに修正して実行します。以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。