今天就跟大家聊聊有關(guān)在Spring Boot 中使用Spring security 如何實(shí)現(xiàn)對(duì)CAS進(jìn)行集成,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。
讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對(duì)這個(gè)行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡(jiǎn)單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價(jià)值的長(zhǎng)期合作伙伴,公司提供的服務(wù)項(xiàng)目有:域名注冊(cè)、網(wǎng)站空間、營(yíng)銷軟件、網(wǎng)站建設(shè)、沙坪壩網(wǎng)站維護(hù)、網(wǎng)站推廣。
1.創(chuàng)建工程
創(chuàng)建Maven工程:springboot-security-cas
2.加入依賴
創(chuàng)建工程后,打開pom.xml,在pom.xml中加入以下內(nèi)容:
org.springframework.boot spring-boot-starter-parent 1.4.3.RELEASE UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-security org.springframework.security spring-security-cas org.springframework.security spring-security-taglibs org.springframework.boot spring-boot-devtools true org.springframework.boot spring-boot-configuration-processor true org.springframework.boot spring-boot-maven-plugin
3.創(chuàng)建application.properties
創(chuàng)建application.properties文件,加入以下內(nèi)容:
#CAS服務(wù)地址 cas.server.host.url=http://localhost:8081/cas #CAS服務(wù)登錄地址 cas.server.host.login_url=${cas.server.host.url}/login #CAS服務(wù)登出地址 cas.server.host.logout_url=${cas.server.host.url}/logout?service=${app.server.host.url} #應(yīng)用訪問地址 app.server.host.url=http://localhost:8080 #應(yīng)用登錄地址 app.login.url=/login #應(yīng)用登出地址 app.logout.url=/logout
4.創(chuàng)建入口啟動(dòng)類(MainConfig)
創(chuàng)建入口啟動(dòng)類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 "訪問了首頁(yè)哦"; } @RequestMapping("/hello") public String hello() { return "不驗(yàn)證哦"; } @PreAuthorize("hasAuthority('TEST')")//有TEST權(quán)限的才能訪問 @RequestMapping("/security") public String security() { return "hello world security"; } @PreAuthorize("hasAuthority('ADMIN')")//必須要有ADMIN權(quán)限的才能訪問 @RequestMapping("/authorize") public String authorize() { return "有權(quán)限訪問"; } /**這里注意的是,TEST與ADMIN只是權(quán)限編碼,可以自己定義一套規(guī)則,根據(jù)實(shí)際情況即可*/ }
5.創(chuàng)建Security配置類(SecurityConfig)
創(chuàng)建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權(quán)限 @EnableGlobalMethodSecurity(prePostEnabled = true) //啟用方法驗(yàn)證 public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private CasProperties casProperties; /**定義認(rèn)證用戶信息獲取來源,密碼校驗(yàn)規(guī)則等*/ @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { super.configure(auth); auth.authenticationProvider(casAuthenticationProvider()); //inMemoryAuthentication 從內(nèi)存中獲取 //auth.inMemoryAuthentication().withUser("chengli").password("123456").roles("USER") //.and().withUser("admin").password("123456").roles("ADMIN"); //jdbcAuthentication從數(shù)據(jù)庫(kù)中獲取,但是默認(rèn)是以security提供的表結(jié)構(gòu) //usersByUsernameQuery 指定查詢用戶SQL //authoritiesByUsernameQuery 指定查詢權(quán)限SQL //auth.jdbcAuthentication().dataSource(dataSource).usersByUsernameQuery(query).authoritiesByUsernameQuery(query); //注入userDetailsService,需要實(shí)現(xiàn)userDetailsService接口 //auth.userDetailsService(userDetailsService); } /**定義安全策略*/ @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests()//配置安全策略 //.antMatchers("/","/hello").permitAll()//定義/請(qǐng)求不需要驗(yàn)證 .anyRequest().authenticated()//其余的所有請(qǐng)求都需要驗(yàn)證 .and() .logout() .permitAll()//定義logout不需要驗(yàn)證 .and() .formLogin();//使用form表單登錄 http.exceptionHandling().authenticationEntryPoint(casAuthenticationEntryPoint()) .and() .addFilter(casAuthenticationFilter()) .addFilterBefore(casLogoutFilter(), LogoutFilter.class) .addFilterBefore(singleSignOutFilter(), CasAuthenticationFilter.class); //http.csrf().disable(); //禁用CSRF } /**認(rèn)證的入口*/ @Bean public CasAuthenticationEntryPoint casAuthenticationEntryPoint() { CasAuthenticationEntryPoint casAuthenticationEntryPoint = new CasAuthenticationEntryPoint(); casAuthenticationEntryPoint.setLoginUrl(casProperties.getCasServerLoginUrl()); casAuthenticationEntryPoint.setServiceProperties(serviceProperties()); return casAuthenticationEntryPoint; } /**指定service相關(guān)信息*/ @Bean public ServiceProperties serviceProperties() { ServiceProperties serviceProperties = new ServiceProperties(); serviceProperties.setService(casProperties.getAppServerUrl() + casProperties.getAppLoginUrl()); serviceProperties.setAuthenticateAllArtifacts(true); return serviceProperties; } /**CAS認(rèn)證過濾器*/ @Bean public CasAuthenticationFilter casAuthenticationFilter() throws Exception { CasAuthenticationFilter casAuthenticationFilter = new CasAuthenticationFilter(); casAuthenticationFilter.setAuthenticationManager(authenticationManager()); casAuthenticationFilter.setFilterProcessesUrl(casProperties.getAppLoginUrl()); return casAuthenticationFilter; } /**cas 認(rèn)證 Provider*/ @Bean public CasAuthenticationProvider casAuthenticationProvider() { CasAuthenticationProvider casAuthenticationProvider = new CasAuthenticationProvider(); casAuthenticationProvider.setAuthenticationUserDetailsService(customUserDetailsService()); //casAuthenticationProvider.setUserDetailsService(customUserDetailsService()); //這里只是接口類型,實(shí)現(xiàn)的接口不一樣,都可以的。 casAuthenticationProvider.setServiceProperties(serviceProperties()); casAuthenticationProvider.setTicketValidator(cas20ServiceTicketValidator()); casAuthenticationProvider.setKey("casAuthenticationProviderKey"); return casAuthenticationProvider; } /*@Bean public UserDetailsService customUserDetailsService(){ return new CustomUserDetailsService(); }*/ /**用戶自定義的AuthenticationUserDetailsService*/ @Bean public AuthenticationUserDetailsServicecustomUserDetailsService(){ return new CustomUserDetailsService(); } @Bean public Cas20ServiceTicketValidator cas20ServiceTicketValidator() { return new Cas20ServiceTicketValidator(casProperties.getCasServerUrl()); } /**單點(diǎn)登出過濾器*/ @Bean public SingleSignOutFilter singleSignOutFilter() { SingleSignOutFilter singleSignOutFilter = new SingleSignOutFilter(); singleSignOutFilter.setCasServerUrlPrefix(casProperties.getCasServerUrl()); singleSignOutFilter.setIgnoreInitConfiguration(true); return singleSignOutFilter; } /**請(qǐng)求單點(diǎn)退出過濾器*/ @Bean public LogoutFilter casLogoutFilter() { LogoutFilter logoutFilter = new LogoutFilter(casProperties.getCasServerLogoutUrl(), new SecurityContextLogoutHandler()); logoutFilter.setFilterProcessesUrl(casProperties.getAppLogoutUrl()); return logoutFilter; } }
6.用戶自定義類
(1)定義CasProperties,用于將properties文件指定的內(nèi)容注入以方便使用,這里不注入也是可以的,可以獲取Spring 當(dāng)前的環(huán)境,代碼如下:
package com.chengli.springboot.properties; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; /** * CAS的配置參數(shù) * @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)定義CustomUserDetailsService類,代碼如下:
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; /** * 用于加載用戶信息 實(shí)現(xiàn)UserDetailsService接口,或者實(shí)現(xiàn)AuthenticationUserDetailsService接口 * @author ChengLi * */ public class CustomUserDetailsService /* //實(shí)現(xiàn)UserDetailsService接口,實(shí)現(xiàn)loadUserByUsername方法 implements UserDetailsService { @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { System.out.println("當(dāng)前的用戶名是:"+username); //這里我為了方便,就直接返回一個(gè)用戶信息,實(shí)際當(dāng)中這里修改為查詢數(shù)據(jù)庫(kù)或者調(diào)用服務(wù)什么的來獲取用戶信息 UserInfo userInfo = new UserInfo(); userInfo.setUsername("admin"); userInfo.setName("admin"); Setauthorities = new HashSet (); AuthorityInfo authorityInfo = new AuthorityInfo("TEST"); authorities.add(authorityInfo); userInfo.setAuthorities(authorities); return userInfo; }*/ //實(shí)現(xiàn)AuthenticationUserDetailsService,實(shí)現(xiàn)loadUserDetails方法 implements AuthenticationUserDetailsService { @Override public UserDetails loadUserDetails(CasAssertionAuthenticationToken token) throws UsernameNotFoundException { System.out.println("當(dāng)前的用戶名是:"+token.getName()); /*這里我為了方便,就直接返回一個(gè)用戶信息,實(shí)際當(dāng)中這里修改為查詢數(shù)據(jù)庫(kù)或者調(diào)用服務(wù)什么的來獲取用戶信息*/ UserInfo userInfo = new UserInfo(); userInfo.setUsername("admin"); userInfo.setName("admin"); Set authorities = new HashSet (); AuthorityInfo authorityInfo = new AuthorityInfo("TEST"); authorities.add(authorityInfo); userInfo.setAuthorities(authorities); return userInfo; } }
(3)定義AuthorityInfo類,用于加載當(dāng)前登錄用戶的權(quán)限信息,實(shí)現(xiàn)GrantedAuthority接口,代碼如下:
package com.chengli.springboot.custom; import org.springframework.security.core.GrantedAuthority; /** * 權(quán)限信息 * * @author ChengLi * */ public class AuthorityInfo implements GrantedAuthority { private static final long serialVersionUID = -175781100474818800L; /** * 權(quán)限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類,用于加載當(dāng)前用戶信息,實(shí)現(xiàn)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; /** * 用戶信息 * @、這里我寫了幾個(gè)較為常用的字段,id,name,username,password,可以根據(jù)實(shí)際的情況自己增加 * @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 Setauthorities = new HashSet (); ....省略getters setters 方法 }
到這里基本就已經(jīng)完成了,運(yùn)行CAS Server ,將以上的application.properties文件中的地址修改為實(shí)際的地址即可運(yùn)行。
看完上述內(nèi)容,你們對(duì)在Spring Boot 中使用Spring security 如何實(shí)現(xiàn)對(duì)CAS進(jìn)行集成有進(jìn)一步的了解嗎?如果還想了解更多知識(shí)或者相關(guān)內(nèi)容,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝大家的支持。