springsecurity整合jwt實現單點登錄

1、使用springsecurity普通登錄 https://mrbird.cc/Spring-Security-Authentication.html

 1-1、Spring Security的核心思想是用戶授權資源認證

  • 資源認證:認證訪問系統的用戶,是調用authenticationManager.authenticate()方法來獲得證書authentication,一般我們採用用戶名、密碼方式認證,那麼authentication的實現類就是UsernamePasswordAuthentication。
  • 用戶授權:是讓用戶可以訪問哪些資源,一般在WebSecurityConfigurerApdater的繼承類中編寫。

 1-2、userService:用戶和密碼是否準確可以寫到裏邊去。

package cc.mrbird.security.browser;

import cc.mrbird.domain.MyUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.authority.AuthorityUtils;
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.security.crypto.password.PasswordEncoder;

@Configuration
public class UserDetailService implements UserDetailsService {

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        System.out.println("username :"+username);
        // 模擬一個用戶,替代數據庫獲取邏輯
        MyUser user = new MyUser();
        user.setUserName(username);
        user.setPassword(this.passwordEncoder.encode("123456"));
        // 輸出加密後的密碼
        System.out.println(user.getPassword());

        return new User(username, user.getPassword(), user.isEnabled(),
                user.isAccountNonExpired(), user.isCredentialsNonExpired(),
                user.isAccountNonLocked(), AuthorityUtils.commaSeparatedStringToAuthorityList("admin"));
    }





}
package cc.mrbird.security.browser;

import cc.mrbird.handler.MyAuthenticationFailureHandler;
import cc.mrbird.handler.MyAuthenticationSucessHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private MyAuthenticationSucessHandler authenticationSucessHandler;

    @Autowired
    private MyAuthenticationFailureHandler authenticationFailureHandler;


    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin() // 表單登錄
                // http.httpBasic() // HTTP Basic
               .loginPage("/authentication/require") // 登錄跳轉 URL
                .loginProcessingUrl("/login") // 處理表單登錄 URL
                .successHandler(authenticationSucessHandler) // 處理登錄成功
                .failureHandler(authenticationFailureHandler) // 處理登錄失敗
                .and()
                .authorizeRequests() // 授權配置
               .antMatchers("/authentication/require", "/login.html").permitAll() // 登錄跳轉 URL 無需認證
                .anyRequest()  // 所有請求
                .authenticated() // 都需要認證
                .and().csrf().disable();
    }
}

2、單點登錄 https://mrbird.cc/Spring-Security-OAuth2-SSO.html

2-1、單點登錄授權模式選擇授權碼模式。 

 2、Client(客戶端)

客戶端配置(必須與oauth服務配置一致)

security.oauth2.client.client-id
指定OAuth2 client ID

security.oauth2.client.client-secret
指定OAuth2 client secret. 默認是一個隨機的secret

security.oauth2.client.user-authorization-uri
用戶跳轉去獲取access token的URI

security.oauth2.client.access-token-uri
指定獲取access token的URI

security.oauth2.resource.jwt.key-uri
JWT token的URI. 當key爲公鑰時,或者value不指定時指定

2、AuthorizationServer  ( 服務中心 )

2-1、AuthorizationServerConfigurerAdapter 

package cc.mrbird.sso.server.config;

import cc.mrbird.sso.server.service.UserDetailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;

/**
 * @author MrBird
 */
@Configuration
@EnableAuthorizationServer
public class SsoAuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private UserDetailService userDetailService;

    @Bean
    public TokenStore jwtTokenStore() {
        return new JwtTokenStore(jwtAccessTokenConverter());
    }

    @Bean
    public JwtAccessTokenConverter jwtAccessTokenConverter() {
        JwtAccessTokenConverter accessTokenConverter = new JwtAccessTokenConverter();
        accessTokenConverter.setSigningKey("test_key");//祕鑰
        return accessTokenConverter;
    }

    //Client和AuthorizationServer配置一致
    //  clients.inMemory()
    //            .withClient("app-a")  //與客戶端配置security.oauth2.client.client-id一致
    //            .secret(passwordEncoder.encode("app-a-1234")) //與客戶端security.oauth2.client.client-secret配置一致     
    //            .authorizedGrantTypes("refresh_token","authorization_code") //刷新授權碼,必須這樣寫
    //            .accessTokenValiditySeconds(3600)        //授權碼有效時間,時間越短越安全
    //            .scopes("all")     //允許授權範圍      
    //           .autoApprove(true)    
    //            .redirectUris("http://127.0.0.1:9090/app1/login")   //登錄地址(本案例採用默認登錄地址,可以自己配)
    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        clients.inMemory()
                .withClient("app-a")  
                .secret(passwordEncoder.encode("app-a-1234"))
                .authorizedGrantTypes("refresh_token","authorization_code")
                .accessTokenValiditySeconds(3600)
                .scopes("all")
                .autoApprove(true)
                .redirectUris("http://127.0.0.1:9090/app1/login")
            .and()
                .withClient("app-b")
                .secret(passwordEncoder.encode("app-b-1234"))
                .authorizedGrantTypes("refresh_token","authorization_code")
                .accessTokenValiditySeconds(7200)
                .scopes("all")
                .autoApprove(true)
                .redirectUris("http://127.0.0.1:9091/app2/login");
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
        endpoints.tokenStore(jwtTokenStore())
                .accessTokenConverter(jwtAccessTokenConverter())
                .userDetailsService(userDetailService);
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) {
        security.tokenKeyAccess("isAuthenticated()"); // 獲取密鑰需要身份認證
    }
}

 2-2、WebSecurityConfigurerAdapter :spring security的默認http配置,可以配置HttpSecurity,包括formLogin,antMatcher,hasRole ,本案例不考慮太多

package cc.mrbird.sso.server.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * @author MrBird
 */
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin()   //表單登錄
            .and()
                .authorizeRequests() 
                .anyRequest()    
                .authenticated();//所有請求必須在登錄後纔可以訪問 
    }
}

2、springsecurity源碼解析 https://blog.csdn.net/qq_30905661/article/details/81082453?depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1&utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-1

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章