1. 程式人生 > >springboot security基於註解配置許可權與CAS單點登入配置。

springboot security基於註解配置許可權與CAS單點登入配置。

1.因產品需求方的要求,我經過考察,使用現今流行的springboot框架,security許可權配置,剛開始碰到不少坑,後來慢慢琢磨,其實發現也就那麼一回事。

2.看本文章前,需要有點springboot對於註解基礎,否則可能不太理解。

這個是我的基本配置,有部分大家可能用不到,我就說一下基本使用的哪些。

WebConfig這個類繼承WebMvcConfigurerAdapter,其實主要是配置攔截器使用的

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {

    @Autowired
    private WebDavConfig webDavConfig;
    
    @Autowired
    private UserSecurityInterceptor securityInterceptor;

 

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new BreadCrumbInterceptor()).addPathPatterns("/**");
        registry.addInterceptor(new WorkWXInterceptor()).addPathPatterns("/**");

        .excludePathPatterns("/login","/logout");//配置登入攔截器攔截路徑
        
     //   registry.addInterceptor(authInterceptor);  //用於跨域時候攔截判斷
    }
    
    @Override  
    public void addCorsMappings(CorsRegistry registry) {  
        registry.addMapping("/**")  
                .allowedOrigins("*")  
                .allowCredentials(true)  
                .allowedMethods("GET", "POST", "DELETE", "PUT")  
                .maxAge(3600);  
    }  

 

    

    @Bean
    public FilterRegistrationBean webDavFilterRegistration() {

        WebDavEngine engine = new WebDavEngine(webDavConfig.getFsPath());

        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(engine.getFilter());
        registration.addUrlPatterns(engine.getResourceRoot());
        registration.setName("webdav");
        registration.setEnabled(webDavConfig.isEnable());
        return registration;

    }

}
主要其實也就一些攔截器配置使用,其它功能其實很少使用到。具體就那樣。

主要的許可權配置還是如下:

public class WebSecurityConfig extends WebSecurityConfigurerAdapter{

}

這個WebSecurityConfig繼承WebSecurityConfigurerAdapter,並重寫它的方法來設定安全許可權



import mobi.shoumeng.oa.entities.base.config.CasProperties;

/**
 * Created by wuyanzhou
 * Copyright @2017
 */

import mobi.shoumeng.oa.services.auth.UserAuthService;
import mobi.shoumeng.oa.services.workwx.auth.WorkWXAuthFilter;
import mobi.shoumeng.oa.services.workwx.auth.WorkWXAuthProvider;

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserAuthService userAuthService;

    @Autowired
    private WorkWXAuthProvider workWXAuthProvider;
    
    @Autowired
    private MyFilterSecurityInterceptor myFilterSecurityInterceptor;
    
    @Autowired  
    private CasProperties casProperties;   //Cas認證
    
    @Autowired
    private UserSecurityInterceptor securityInterceptor;
    
   
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http
                .authorizeRequests()
                .antMatchers("/weixin","/favicon.ico", "/js/*","/css/*","/jquery-ui-timepicker-addon/*","/images/*", "/fonts/*", "/caldav", "/carddav", "/files/").permitAll()//這些靜態可以全部許可權訪問
                .anyRequest().authenticated()
                .and()
                //增加企業微信登入處理
                .addFilterAfter(getWorkWXAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class)
                .csrf().disable()
                .formLogin().loginPage("/login")//登入頁面
                .defaultSuccessUrl("/#/notice/index",true)//預設跳轉
                .permitAll()
                .and()
//                .rememberMe()
//                .tokenValiditySeconds(360000)
//                .userDetailsService(userAuthService)
//                .useSecureCookie(true)
//                .and()
                .headers()
                .defaultsDisabled()
                .contentTypeOptions();
          
        http.sessionManagement()   //配置session的功能
        .maximumSessions(1)
        .maxSessionsPreventsLogin(false)  //這個功能很強悍,我這樣配置,你的登入會把賬號擠出去
        .expiredUrl("/login")
        .sessionRegistry(sessionRegistry());//session的其他註冊配置
        
        
        
       http.logout()
       .logoutUrl("/logout")
       .logoutSuccessUrl(casProperties.getCasServerLogoutUrl())  //這個是登出時候跳到單點伺服器上面,把單點登出了賬號
       .invalidateHttpSession(true)   //初始化
       .clearAuthentication(true)//清除許可權
       .invalidateHttpSession(true)
       .permitAll();
        
      http.addFilterBefore(myFilterSecurityInterceptor, FilterSecurityInterceptor.class);

   //   http.exceptionHandling().accessDeniedPage("/Jurisdiction/insufficientAuthority"); //嘗試測試
      //session等待時間
     // http.sessionManagement().wait(1800);
      
      http.exceptionHandling()
      .accessDeniedPage("/Jurisdiction/insufficientAuthority")  //當頁面沒有許可權的時候,跳轉地方
      .authenticationEntryPoint(casAuthenticationEntryPoint())  //單點登入的認證入口
      .and()  
      .addFilter(casAuthenticationFilter())  //記得新增攔截器
      .addFilterBefore(casLogoutFilter(), LogoutFilter.class)  //新增登出攔截器
      .addFilterBefore(singleSignOutFilter(), CasAuthenticationFilter.class);   
     
      
      
    }

    private WorkWXAuthFilter getWorkWXAuthenticationFilter() throws Exception {

        WorkWXAuthFilter filter = new WorkWXAuthFilter();//微信登入設定驗證
        filter.setAuthenticationManager(authenticationManager());
        return filter;

    }
    
    
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {

        auth
                .userDetailsService(userAuthService)//使用者驗證
                .passwordEncoder(new ShaPasswordEncoder())//加密演算法,使用sh1
                .and()
                .authenticationProvider(workWXAuthProvider);//微信登入的驗證入口
      
       
                auth.authenticationProvider(casAuthenticationProvider());  //單點登入驗證
    }
    
    // Work around https://jira.spring.io/browse/SEC-2855
    @Bean
    public SessionRegistry sessionRegistry() {
        SessionRegistry sessionRegistry = new SessionRegistryImpl();
        return sessionRegistry;
    }
    @Bean
    public static ServletListenerRegistrationBean httpSessionEventPublisher() {
        return new ServletListenerRegistrationBean(new HttpSessionEventPublisher());
    }
    
    
    
    
    
    /**認證的入口*/  
    @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(userAuthService);//這個是我自己配置,根據自己需要配置
        //casAuthenticationProvider.setUserDetailsService(customUserDetailsService()); //這裡只是介面型別,實現的介面不一樣,都可以的。  
        casAuthenticationProvider.setServiceProperties(serviceProperties());  
        casAuthenticationProvider.setTicketValidator(cas20ServiceTicketValidator());  
        casAuthenticationProvider.setKey("casAuthenticationProviderKey");  
        return casAuthenticationProvider;  
    }  
      
//   @Bean
//    public UserDetailsService UserDetailsService(){
//        return new UserAuthService();
//    }
      
//    /**使用者自定義的AuthenticationUserDetailsService*/  
//    @Bean  
//    public AuthenticationUserDetailsService<CasAssertionAuthenticationToken> customUserDetailsService(){  
//        return new UserAuthService();  
//    }  
      
    @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() {  //這個地方要注意,service需要你在單點伺服器上面配置那邊配置跳轉,會跳轉你需要的頁面,否則跳不回來
        LogoutFilter logoutFilter = new LogoutFilter(casProperties.getCasServerLogoutUrl()+"?service=" + casProperties.getAppServerUrl() + casProperties.getAppLoginUrl(), new SecurityContextLogoutHandler());  
        logoutFilter.setFilterProcessesUrl(casProperties.getAppLogoutUrl());  
        return logoutFilter;  
    }  
}  
    
    

@Component
public class UserAuthService implements UserDetailsService{//, AuthenticationUserDetailsService<CasAssertionAuthenticationToken>  {

    @Autowired
    private UserRepository userRepository;
  
    
    @Autowired
    DepartementServiceImpl departementServiceImpl;
    
    @Autowired
    PepopleServiceImpl  pepopleServiceImpl;
    
    @Autowired
    CommentSession commentSession;
    
    @Autowired
    HttpServletRequest request;
    
    @Autowired
    UserRoleServiceImpl userRoleServiceImpl;
    

    

    @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        List<GrantedAuthority> grantedAuthorities = new ArrayList <>();
        User user = userRepository.findByLoginAccount(s);
        if(user.getUseif()!=1){
            return null;
        }
        UserRole userRole = user.getUserRole();
        UserRole findByUserRole = userRoleServiceImpl.findByUserRole(userRole.getId());
    //     System.out.println("測試角色"+userRole.getName());
        Set<UserPermission> userPermissions = findByUserRole.getUserPermissions();
        for(UserPermission se:userPermissions){
            // System.out.println("測試列表"+se.getName());
             GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(se.getName());
             //1:此處將許可權資訊新增到 GrantedAuthority 物件中,在後面進行全許可權驗證時會使用GrantedAuthority 物件。
             grantedAuthorities.add(grantedAuthority);
        }
       
        if (Objects.isNull(user)) {
            
            
            throw new UsernameNotFoundException(String.format("使用者名稱[%s]未找到", s));
        }
   
        org.springframework.security.core.userdetails.User sysuser=new org.springframework.security.core.userdetails.User(user.getUsername(),user.getPassword(),grantedAuthorities);
         return sysuser;

    }

上面的許可權必須使用者表必須實現介面User implements UserDetails, Serializable

本人的許可權是直接在UserDetails設定,這樣避免一些實體類上的問題。許可權是根據你的角色裡面資源載入,把你的資源URL匹配。

其它的許可權驗證和網上很多資料差不多,就是配置一下過濾器過濾URL,把每個你配置URL判斷是否該資源有沒有許可權問題等。

 public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes) throws AccessDeniedException, InsufficientAuthenticationException {

        if(null== configAttributes || configAttributes.size() <=0) {
            return;
        }
        ConfigAttribute c;
        String needRole;
        for(Iterator<ConfigAttribute> iter = configAttributes.iterator(); iter.hasNext(); ) {
            c = iter.next();
            needRole = c.getAttribute();
            for(GrantedAuthority ga : authentication.getAuthorities()) {//authentication 為在註釋1 中迴圈新增到 GrantedAuthority 物件中的許可權資訊集合
                if(needRole.trim().equals(ga.getAuthority())) {
                    return;
                }
            }
        }
  

總體上講的可能不是很全面,但是基本的配置已經有註解和講說。可能有部分沒有複製上去,不過網上已經很多資料可以查閱,我的方法其實主要配置已經是非常完善。

有什麼技術上的問題,也可以加我的QQ詢問我。可能平時不線上,也可以留言。。一位開發者的分享。

相關推薦

springboot security基於註解配置許可權CAS登入配置

1.因產品需求方的要求,我經過考察,使用現今流行的springboot框架,security許可權配置,剛開始碰到不少坑,後來慢慢琢磨,其實發現也就那麼一回事。 2.看本文章前,需要有點springboot對於註解基礎,否則可能不太理解。 這個是我的基本配置,有部分大家可

cas 登入配置

官方下載,支援maven的最新版本是5.3 https://github.com/apereo/cas-overlay-template/tree/5.3 預設是沒有src資料夾的需求手動建立, application.properties 檔案在build後會生成在classes資料夾中copy進來就好。然

CAS登入-配置資料庫認證方式

接下來,說一下配置資料庫認證單點登入 如果你之前的單點登入搭成功了,之後就簡單多了,只需要新增一些配置和jar包即可。若未成功,請參考CAS單點登入入門配置 步驟: 1、引入相關jar包 2、建立資料庫和表,填入資料 3、修改配置檔案 4、部署,啟動tomcat 完成 1

jasig cas登入配置筆記之五

以上配置完成後還有一點問題,就是cas client的配置完成後,登入A應用,然後登入B應用,需要重新認證. 仔細閱讀文件,發現原來jasig Cas不能支援非SSL方式的統一登入.實際上登入首頁上已經提示: Non-secure Connection You ar

第三部分:shiro整合spring使用cas登入配置

第三部分 shiro整合spring使用cas單點登入配置 (一)shiro單點登入   配置的主要目的在於將登入頁面改為${cas.server}?service=${cas.client}/login的形式,service後面為本地的回撥地址。在ca

Cas登入配置SSL時遇到的javax.net.ssl.SSLPeerUnverifiedException問題的解決方法

網上有很多資料介紹如何整合CAS單點登入產品。由於整合CAS需要預先在tomcat中配置SSL,而且還要在客戶端匯入證書,但是許多人按照網上介紹的操作操作卻發現以下問題:儘管配置了SSL後可以訪問也能登入但是在位址列輸入自己的Web應用的連線,自動跳到Cas登入頁面,登入成

cas登入 (二) 客戶端springboot整合

在springboot專案中實現cas單點登入統一認證,只需要在專案中配置 cas過濾器即可使用. 1. springboot專案pom.xml中 新增web支援依賴 、cas客戶端依賴包 <dependency> <groupId>org

asp net專案開源登入專案CAS的結合

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

CAS登入(一)——登入CAS理論介紹

一、什麼是單點登入(SSO)   單點登入主要用於多系統整合,即在多個系統中,使用者只需要到一箇中央伺服器登入一次即可訪問這些系統中的任何一個,無須多次登入。   單點登入(Single Sign On),簡稱為 SSO,是目前比較流行的企業業務整合的解決方案之一。SSO的定義是在多個應用系統中,使用者只

CAS登入(3):cas-4.0.0 客戶端配置

新建web工程 新增依賴jar包 cas-client-core-3.2.1.jar commons-logging-1.2.jar Tips: Maven專案直接新增Pom: <dependency> <grou

CAS登入(4):cas-4.0.0-server 配置mysql資料庫查詢認證

目錄 目錄 概述 環境要求 建立資料庫 Tips 配置cas-server 配置dataSource 配置passwordEnco

CAS登入-客戶端整合(shiro、springboot、jwt、pac4j)(十)

CAS單點登入-客戶端整合(shiro springboot jwt pac4j)(十) 由於我們通常在業務上會有以下的使用場景: 移動端通過業務系統鑑權 移動端免登入(登入一次以後) 解決方案: JWT(token認證方案) OAuth(第三方認

SpringBoot整合cas登入

注意:(1).  專案使用了lombok工具包            (2).  在CasConfig中配置了原web.xml中cas的過濾器和監聽器 1、(1).  定義一個類CasAutoconfig用於放置cas的一些屬性配置 import org.springfr

Jasig cas 登入系統Server&Java Client配置

Jasig cas(Central Authentication Service)官方站點:http://www.jasig.org/cas,訪問這個站點需要翻牆。 cas官網文件訪問地址:https://wiki.jasig.org/display/CASUM/Hom

cas登入整合spring security

在學習security的過程中接觸到了cas,並學習了cas的配置和整合security    Cas伺服器端的配置     一、使用java keytool工具為系統生成Https證書,並註冊 1.刪除已有的證書 C:\Program Files\Java\jdk1.6

cas登入spring boot關聯使用

1.cas單點登入介紹 單點登入( Single Sign-On , 簡稱 SSO )是目前比較流行的服務於企業業務整合的解決方案之一, SSO 使得在多個應用系統中,使用者只需要 登入一次 就可以訪問所有相互信任的應用系統。 從結構體系看,

Cas登入客戶端配置

一直不喜歡說太多東西,直接上程式碼。     主要是以下幾個步驟: 1、專案加入cas-client-core-3.2.1.jar到lib中         2、匯入證書(此步驟根據專案判斷是否需要操作)         3、配置web.xml         4、編寫客戶

nginx配置反向代理CAS登錄應用

efault clas fault header oca timeout 代理 反向 redirect 新增如下配置即可: location /cas { proxy_pass http://172.16.20.155:8080/cas; prox

CAS登入系列之極速入門實戰教程(4.2.7)

@目錄一、 SSO簡介1.1 單點登入定義1.2 單點登入角色1.3 單點登入分類二、 CAS簡介2.1 CAS簡單定義2.2 CAS體系結構2.3 CAS原理三、CAS服務端搭建3.1 CAS支援Http登入配置3.2 CAS服務端部署執行四、CAS客戶端接入五、客戶端極速接入 一、 SSO簡介 1.1 單

CAS統一登入認證(16): openedx 通過oauth2.0接入cas登入

openedx 是流行的開源mooc(慕課)平臺,我這安裝的是edx-ginkgo.2-7版本,cas是5.3.2 這個接入頗費了一番周折,總是設定不成功,因為沒有可以直接參考的案例,只有edx的官方站點有些說明,但都是針對google,facebook,github等賬號的第三方oauth2.