springboot springsecurity cas集成

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014161595/article/details/87913595

1.添加依赖jar

<!-- spring security -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <!-- cas -->
    <dependency>
           <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-cas</artifactId>
    </dependency>

2.extends WebSecurityConfigurerAdapter

注意:MyUserDetailsService implements UserDetailsService , AuthenticationUserDetailsService<CasAssertionAuthenticationToken>一定要实现AuthenticationUserDetailsService<CasAssertionAuthenticationToken>,cas服务器认证通过后会回调此接口的public UserDetails loadUserDetails(CasAssertionAuthenticationToken token)方法。

关键代码添加过滤器Filter链:

 http.exceptionHandling().authenticationEntryPoint(casAuthenticationEntryPoint(serviceProperties()));
        // 单点注销的过滤器,必须配置在SpringSecurity的过滤器链中,如果直接配置在Web容器中,貌似是不起作用的。我自己的是不起作用的。
        SingleSignOutFilter singleSignOutFilter = new SingleSignOutFilter();
        singleSignOutFilter.setCasServerUrlPrefix(this.casServerConfig.getHost());
        
        http.addFilter(casAuthenticationFilter())
                .addFilterBefore(logoutFilter(), LogoutFilter.class)
                .addFilterBefore(singleSignOutFilter, CasAuthenticationFilter.class);

在application.properties添加:

security.cas.server.host = http://192.168.10.95:8080/cas
security.cas.server.login = ${security.cas.server.host}/login
security.cas.server.logout = ${security.cas.server.host}/logout

security.cas.service.host = http://192.168.10.95:8088
security.cas.service.login = /login
security.cas.service.logout = /logout

创建@Component
@ConfigurationProperties(prefix = "security.cas.server")

扫描二维码关注公众号,回复: 5415180 查看本文章

public class CasServerConfig类和@Component
@ConfigurationProperties(prefix = "security.cas.service")
public class CasServiceConfig 类

以下为实现代码:

package pit.security;

import java.util.ArrayList;

import javax.annotation.Resource;
import javax.sql.DataSource;

import org.jasig.cas.client.session.SingleSignOutFilter;
import org.jasig.cas.client.validation.Cas30ServiceTicketValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.ProviderManager;
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.crypto.password.MessageDigestPasswordEncoder;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutFilter;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true) //启用方法验证
public class PitWebSecutiryConfig extends WebSecurityConfigurerAdapter{
    @Bean
    MyUserDetailsService myUserDetailsService(){
        return new MyUserDetailsService();
    }
    @Resource
    private DataSource dataSource;
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                .antMatchers("/js/**","/css/**","/login**").permitAll()
                .anyRequest().authenticated()
                .and()
            .formLogin()
            .loginPage("/login.html").loginProcessingUrl("/login").permitAll()
//            .defaultSuccessUrl("/")
            .and()
            .logout().logoutUrl("/logout").logoutSuccessUrl("/login").invalidateHttpSession(true).deleteCookies("JSESSIONID")
            .and()
            .csrf().disable();
        http.exceptionHandling().authenticationEntryPoint(casAuthenticationEntryPoint(serviceProperties()));
        // 单点注销的过滤器,必须配置在SpringSecurity的过滤器链中,如果直接配置在Web容器中,貌似是不起作用的。我自己的是不起作用的。
        SingleSignOutFilter singleSignOutFilter = new SingleSignOutFilter();
        singleSignOutFilter.setCasServerUrlPrefix(this.casServerConfig.getHost());
        
        http.addFilter(casAuthenticationFilter())
                .addFilterBefore(logoutFilter(), LogoutFilter.class)
                .addFilterBefore(singleSignOutFilter, CasAuthenticationFilter.class);

//        http.antMatcher("/**");
    }
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
//        auth.userDetailsService(myUserDetailsService()).passwordEncoder(new MessageDigestPasswordEncoder("MD5"));
//        auth.jdbcAuthentication().dataSource(dataSource)
//            .usersByUsernameQuery("SELECT COM_NUM,LOWER(User_Password),User_Validity FROM UserT where COM_NUM= ?")
//            .authoritiesByUsernameQuery("SELECT COM_NUM,RESOURCE FROM T_USER_RESOURCES WHERE COM_NUM= ?")
//            .passwordEncoder(new MessageDigestPasswordEncoder("MD5"));
        auth.authenticationProvider(casAuthenticationProvider());
    }
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
//        ArrayList<AuthenticationProvider> list=new ArrayList<AuthenticationProvider>();
//        list.add(casAuthenticationProvider());
//        return new ProviderManager(list);
        return super.authenticationManagerBean();
    }
    
    
    
    
    
    
    
    @Autowired
    private CasServerConfig casServerConfig;

    @Autowired
    private CasServiceConfig casServiceConfig;

    @Bean
    public ServiceProperties serviceProperties() {
        ServiceProperties serviceProperties = new ServiceProperties();
        serviceProperties.setService(this.casServiceConfig.getHost() + this.casServiceConfig.getLogin());
        serviceProperties.setSendRenew(this.casServiceConfig.getSendRenew());
        return serviceProperties;
    }

    @Bean
    public CasAuthenticationFilter casAuthenticationFilter() throws Exception {
        CasAuthenticationFilter casAuthenticationFilter = new CasAuthenticationFilter();
        casAuthenticationFilter.setAuthenticationManager(authenticationManagerBean());
        casAuthenticationFilter.setServiceProperties(serviceProperties());
        casAuthenticationFilter.setFilterProcessesUrl(this.casServiceConfig.getLogin());
        casAuthenticationFilter.setContinueChainBeforeSuccessfulAuthentication(false);
        casAuthenticationFilter.setAuthenticationSuccessHandler(
                new SimpleUrlAuthenticationSuccessHandler("/")
        );
        return casAuthenticationFilter;
    }
    @Bean
    public CasAuthenticationEntryPoint casAuthenticationEntryPoint(ServiceProperties serviceProperties) {
        CasAuthenticationEntryPoint entryPoint = new CasAuthenticationEntryPoint();
        entryPoint.setLoginUrl(this.casServerConfig.getLogin());
        entryPoint.setServiceProperties(serviceProperties);
        return entryPoint;
    }

    @Bean
    public Cas30ServiceTicketValidator cas30ServiceTicketValidator() {
        return new Cas30ServiceTicketValidator(this.casServerConfig.getHost());
    }

    @Bean
    public CasAuthenticationProvider casAuthenticationProvider() {
        CasAuthenticationProvider provider = new CasAuthenticationProvider();
        provider.setKey("casProvider");
        provider.setServiceProperties(serviceProperties());
        provider.setTicketValidator(cas30ServiceTicketValidator());
        provider.setAuthenticationUserDetailsService(customUserDetailsService());

        return provider;
    }
    @Bean
    public AuthenticationUserDetailsService<CasAssertionAuthenticationToken> customUserDetailsService(){
        return new MyUserDetailsService();
    }
    @Bean
    public LogoutFilter logoutFilter() {
        String logoutRedirectPath = this.casServerConfig.getLogout();
//                + "?service=" +
//                this.casServiceConfig.getHost();
        LogoutFilter logoutFilter = new LogoutFilter(logoutRedirectPath, new SecurityContextLogoutHandler());
        logoutFilter.setFilterProcessesUrl(this.casServiceConfig.getLogout());
        return logoutFilter;
    }
}

package pit.security;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.cas.authentication.CasAssertionAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import pit.dao.UserTMapper;
import pit.model.UserT;
@Component
public class MyUserDetailsService implements UserDetailsService , AuthenticationUserDetailsService<CasAssertionAuthenticationToken>{
    @Autowired
    private UserTMapper utMapper;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        List<SimpleGrantedAuthority> authorities = new ArrayList<>();
        //对应的权限添加
        authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
        UserT usert=utMapper.selectByComnum(username);
        User user=new User(username, usert.getUserPassword().toLowerCase(), authorities);
        return user;
    }
    @Override
    public UserDetails loadUserDetails(CasAssertionAuthenticationToken token) throws UsernameNotFoundException {
        System.out.println("==========当前的用户名是:"+token.getName());
        String username=token.getName();
        List<SimpleGrantedAuthority> authorities = new ArrayList<>();
        //对应的权限添加
        authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
        UserT usert=utMapper.selectByComnum(username);
        User user=new User(username, usert.getUserPassword().toLowerCase(), authorities);
        return user;
    }

}
 

package pit.security;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "security.cas.server")
public class CasServerConfig {
    private String host;
    private String login;
    private String logout;
    public String getHost() {
        return host;
    }
    public void setHost(String host) {
        this.host = host;
    }
    public String getLogin() {
        return login;
    }
    public void setLogin(String login) {
        this.login = login;
    }
    public String getLogout() {
        return logout;
    }
    public void setLogout(String logout) {
        this.logout = logout;
    }
    
}
 

package pit.security;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "security.cas.service")
public class CasServiceConfig {
    private String host;
    private String login;
    private String logout;
    private Boolean sendRenew = false;
    public String getHost() {
        return host;
    }
    public void setHost(String host) {
        this.host = host;
    }
    public String getLogin() {
        return login;
    }
    public void setLogin(String login) {
        this.login = login;
    }
    public String getLogout() {
        return logout;
    }
    public void setLogout(String logout) {
        this.logout = logout;
    }
    public Boolean getSendRenew() {
        return sendRenew;
    }
    public void setSendRenew(Boolean sendRenew) {
        this.sendRenew = sendRenew;
    }
    
}

参考文档:

https://www.jianshu.com/p/3c4a007b0dcc

https://blog.csdn.net/u010475041/article/details/79592661

https://blog.csdn.net/cl_andywin/article/details/53998986

https://blog.csdn.net/weixin_40295896/article/details/78021062

超时设置:

https://blog.csdn.net/qq_17348297/article/details/81807221

猜你喜欢

转载自blog.csdn.net/u014161595/article/details/87913595