1. 程式人生 > 其它 >怎麼設計樹狀管理後臺_微服務架構實戰:商家管理後臺與sso設計:SSO設計

怎麼設計樹狀管理後臺_微服務架構實戰:商家管理後臺與sso設計:SSO設計

技術標籤:怎麼設計樹狀管理後臺

SSO設計

Spring Security是一個功能強大、可定製的身份驗證和訪問控制框架.Spring Security OAuth2是一個基於Spring框架支援第三方應用授權的工具元件。通過使用Spring Security OAuth2,我們可以在商家後臺中進行單點登入(SSO)設計,從而為多個微服務應用的系統整合,使用統一的安全控制管理。

SSO設計分為服務端和客戶端兩大部分。SSO服務端為每個應用提供了統一的訪問控制和授權認證服務,是一個Web UI微服務應用,在模組merchant-sso中進行開發,包含了使用者登入設計、主頁設計和認證服務設計等方面的內容。SSO客戶端是指為使用者提供本地服務的程式

SSO的基本配置

SSO的基本配置與一般的Web UI應用專案配置基本相同,即在 Web UI應用專案配置的基礎上,增加 Spring Cloud OAuth2的依賴引用,程式碼如下所示:

org.springframework.cloudspring-cloud-starter-oauth2

這個元件已經包含了Security 和OAuth2兩套元件體系,其中,Security提供了訪問控制功能,OAuth2提供了第三方應用授權認證的服務。

在應用的配置檔案 application.yml中,設定SSO應用的服務埠,並設定一個cookie儲存使用者的登入資訊,程式碼如下所示:

server:port:8000session:cookie:name: SESSIONID

為保證第三方應用在授權之後能夠被正常訪問,我們必須在配置檔案中增加接入SSO客戶端返回地址的列表,並使用正確的格式“http:/l域名或IP:埠/login”進行設定,程式碼如下所示;

#SSo客戶端返回地址的列表ssoclient:redirecturis:- http://localhost:8081/login- http://127.0.0.1:8081/1ogin

sso第三方應用授權設計

為了給接入SSO的第三方應用(這裡指接入SSO服務的其他微服務應用)進行授權,我們建立了一個配置類AuthServerConfig,它繼承了AuthorizationServerConfigurerAdapter,程式碼如下所示:

@[email protected]@EnableConfigurationProperties(clienturls.class)public class authServerConfig extends AuthorizationServerConfigurerAdapterCAutowiredprivate Clienturls clienturls;@Overridepublic void configure (AuthorizationServerSecurityConfigurer oauthServer)throws Exception {oauthServer.tokenKeyAccess( "permitAll ()").checkTokenAccess("isAuthenticated()");@overridepublic void configure (ClientDetailsServiceConfigurer clients) throwsException {clients.inMemory().withClient ( "ssoclient").secret(passwordEncoder ().encode ("ssosecret")).authorizedGrantTypes ("authorization_code").scopes ( "user_info").autoApprove(true).redirectUris(clienturls.getRedirecturis());@Beanpublic JwtAccessTokenConverter jwtAccessTokenConverter() {JwtAccessTokenConverter converter = new JwtAccessTokenConverter();converter. setSigningKey ( "demoSige");return converter;}aoverridepublic void configure(AuthorizationServerEndpointsConfigurer endpoints)throws Exception {endpoints.accessTokenConverter(jwtAccessTokenConverter());}@Beanpublic BCryptPasswordEncoder passwordEncoder(){return new BCryptPasswordEncoder();}}

在上面的配置類中,包含以下主要功能:

(1)使用註解@EnableAuthorizationServer 開啟 SSO伺服器的功能。(2)重寫第一個configure,開啟使用Token進行授權的功能。

(3)重寫第二個 configure,為客戶端指定表單頁面授權的方式,即 authorization_code,並且設定客戶端授權時使用的使用者名稱和密碼分別為ssoclient和 ssosecret。同時,匯入配置中的客戶端返回地址列表,並設定客戶端返回地址列表為redirectUris。另外,通過 autoApprove(true)設定為自動確認授權,省略了客戶端授權時必須手動確認的步驟。

(4)重寫第三個configure,使用安全的JwtAccessToken。這裡有關金鑰的使用,我們只簡單地使用一個文字 demoSige,如果想使用更加安全的方式,則可以使用KeyStore生成金鑰進行配置。

sso登入認證設計

下面提供一個登入介面,用來接收使用者輸入的使用者名稱和密碼等資訊,實現使用者登入操作。在登入認證中,使用Spring Security對使用者名稱和密碼進行驗證。

建立一個MyUserDetails類,實現Spring Security 的 UserDetails,程式碼如下所示:

public class MyUserDetails implements UserDetails {private string username;private String password;private Collection extends GrantedAuthority> authorities;private User user;public MyUserDetails(String username, String password, collection extendsGrantedAuthority>authorities, User user){this.username = username;this.password = password;this.authorities = authorities;this.user = user;}...}

這樣就可以匯入我們自定義的使用者體系,提供給Spring Security進行認證了。

建立一個MyUserDetailsService類,實現Spring Security 的UserDetailsService,為接下來的認證服務提供使用者資訊和匯入使用者的角色,程式碼如下所示:

@componentpublic class MyUserDetailsService implements UserDetailsService {@Autowiredprivate UserService userService;@overridepublic UserDetails loadUserByUsername (String username) throwsUsernameNotFoundException {User user = userService.findByName (username);if(user==nul1){throw new UsernameNotFoundException("使用者不存在!");}List authorities = new ArrayList<>();List roles =user.getRoles ();if(roles !=null){for(Role role : roles) {SimpleGrantedAuthority authority = newSimpleGrantedAuthority(role.getName ());authorities.add(authority);}}MyUserDetails myUserDetails = new MyUserDetails (username,user.getPassword(),authorities, user);return myUserDetails;}}

這樣,當Spring Security進行認證時,就會呼叫我們的使用者並且取得相關的角色,從而完成登入時的使用者名稱和密碼驗證,並且為使用者配置相應的許可權。

為了讓上面的設計生效,我們還需要建立一個配置類,即 SecurityConfng 尖o匕繼承」SprngSecurity 的 WebSecurityConfigurerAdapter,程式碼如下所示:

@Configurationpublic class SecurityConfig extends [email protected] MyUserDetailsService myUserDetailsService;@[email protected]("dataSource")private DataSource dataSource;@Bean(name = BeanIds.AUTHENTICATION MANAGER)Goverridepublic AuthenticationManager authenticationManagerBean () throws Exceptionreturn super.authenticationManagerBean();@overrideprotected void configure (AuthenticationManagerBuilder auth)throws Exception {auth //lremember me.eraseCredentials(false).userDetailsService (myUserDetailsService).passwordEncoder (newBCryptPasswordEncoder());@Overrideprotected void configure(HttpSecurity http) throws Exceptionhttp.antMatcher("/**").authorizeRequests().antMatchers( "/login").permitAl1().antMatchers(" /images/**", "/checkcode", "/scripts/*"/styles/**").permitAll().anyRequest().authenticated().and ().sessionManagement ().sessionCreationPolicy(SessionCreationPolicy.NEVER).and(.exceptionHandling().accessDeniedPage ("/deny").and().rememberMe ().tokenValiditySeconds (86400).tokenRepository(tokenRepository()).and().formLogin().loginPage ("/login" ).permitAll ().successHandler(loginsuccessHandler()).and() .logout().logoutUrl("/logout").permitAll().logoutSuccessUrl ("/signout");}@Beanpublic JdbcTokenRepositoryImpl tokenRepository()JdbcTokenRepositoryImpl jtr = new JdbcTokenRepositoryImpl()jtr.setDataSource(dataSource);return jtr;}@Beanpublic LoginSuccessHandler loginsuccessHandler(){return new LoginSuccessHandler();}}

在這個配置類中,做了如下設定:

(1)設定使用者服務為上面定義的MyUserDetailsService。

(2)指定登入頁面連結為/login,這樣可以通過控制器設計指定檢視檔案。

(3)指定登入成功的處理程式loginSuccessHandler。

4)忽略對圖片等靜態資源的驗證。

(5)指定拒絕訪問的錯誤提示連結/deny。

(6)使用rememberMe()設定來記住使用者的登入狀態。

(7)指定使用本地資料來源儲存使用者登入狀態的臨時資料。

針對上面的配置類設計,我們建立一個控制器,設定一個登入連結/login,併為其指定一個介面設計頁面login.html,程式碼如下所示:

@Controllerpublic class LoginController {@RequestMapping( "/1ogin")public String login(){return "login";)}

在介面設計頁面login.html中,主要使用一個表單設計,提供具有使用者名稱和密碼等輸入控制元件的登入介面,程式碼如下所示:

...
更新 本頁面已經失效。請點選此處重新登入。div class="check-box">span class="toggleCheck no-check" id="repwd">記住我