日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

Shiro和Security的核心模塊以及兩者的區別

作者:不隨意的風 更新時間: 2022-09-05 編程語言

Shiro:

Subject:

subject主題,外部應用與subject進行交互,subject將用戶作為當前操作的主體,這個主體:可以是一個 通過瀏覽器請求的用戶,也可能是一個運行的程序。subject在shiro中是一個接口,接口中定義了很多認證授權的方法,外部程序通過subject進行認證授權,而subject是通過SecurityManager安全管理器進行認證鑒權。

Securitymanager:

securitymanager權限管理器,它是shiro的核心,負責對所有的subject進行安全管理。通過securityManager可以完成subject的認證、授權等,SecurityManager是通過Authentication進行認證,通過Authorizer進行授權,通過SessionManager進行會話管理等。SecurityManager是一個接口,繼承了Authentication,Authorizer,SessionManager這三個接口。

Authenticator:

Authenticator即認證器,對用戶登錄時進行身份認證。

Authorizer:

Authorizer授權器,用戶通過認證器認證通過,在訪問功能時需要授權器判斷用戶是否有此功能的操作權限。

Realm(數據庫讀取+認證功能+授權功能實現):

Realm領域,相當于datasource數據源,securityManager進行安全認證需要通過Realm獲取用戶權限數據。

比如:如果用戶身份數據在數據庫那么realm就需要從數據庫獲取用戶身份信息。

注意:不要把realm理解從只是從數據源獲取數據,在realm中還有認證授權校驗的相關的代碼。

SessionManager:

SessionManager會話管理,shiro框架定義了一套繪畫管理,它不依賴web容器的session,所以shiro可以使用在非web應用上,也可以將分布式應用的會話集中在一點管理,此特性可使它實現單點登錄。

SessionDAO:

SessionDAO即會話dao,是對session會話操作的一套接口

比如:可以通過jdbc將會話存儲到數據庫,也可以把session存儲到緩存服務器。

CacheManager:

CacheManager緩存管理,將用戶權限數據存儲在緩存,這樣可以提高性能。

Cryptography:

Cryptography密碼管理,shiro提供了一套加密/解密的組件,方便開發。比如提供常用的散列、加/解密等功能。

UsernamePasswordToken(用戶登錄信息令牌):

用戶登錄信息令牌,這個對象中封裝了用戶的登錄信息,主要包括用戶名和密碼,在登錄的時候會創建這個令牌。

Spring Security:

Spring 安全性是提供認證、授權和防范常見攻擊的框架。由于對imperative和reactive應用程序的安全都提供了第一類支持,因此它是保護基于 Spring 的應用程序的事實上的標準。

SecurityContextHolder

SecurityContextHolder它持有的是安全上下文(SecurityContext)的信息。當前操作的用戶是誰,誰用戶是否已經被認證,他擁有那些角色權等等,這些都被保存在SecurityContextHolder中。SecurityContextHolder默認使用ThreadLocal策略來存儲認證信息。看到ThreadLocal也就意味著,這是一種與線程綁定的策略。在web環境下,springsecurity在用戶登錄時自動綁定認證信息到當前線程,在用戶退出時,自動清除當前線程的認證信息。

SecurityContext

安全上下文,主要持有Authentication對象,如果用戶未鑒權,那么Authentication對象將會空的。該示例可以通過SecurityContextHolder.getContext靜態方法獲取。

Authentication

鑒權對象,該對象注意包含了用戶的詳細信息(UserDetails)和用戶鑒權時所需要的信息,如用戶提價奧的用戶密碼、Remember-me Token,或者digestHash值等,按不同鑒權方式使用不同的Authentication實現。

Authentication是spring security包中的接口,直接繼承自Principal類,而Principal是位于java.security包中的。可以見得,Authentication在spring security中是最高級別的身份/認證的抽象。由這個頂級接口,我們可以得到用戶擁有的權限信息列表,密碼,用戶細節信息,用戶身份信息,認證信息。

GrantedAuthority

該接口表示了當前用戶所有的權限(或者角色)信息。這些信息有授權負責對象AccessDecisionManager來使用,并覺得最終用戶是否可以訪問某資源。(URL或方法調用或域對象)。鑒權時并不會使用到該對象。

UserDetails

這個接口規范了用戶詳細信息所擁有的字段,譬如用戶名、密碼、賬號是否過期、是否鎖定等。在SpringSecurity中,獲取當前登錄的用戶的信息,一般情況時需要在這個接口上面進行擴展,用來對接自己系統的用戶。

UserDetailsService

這個接口只提供一個接口loadUserByUsername(String username),這個接口非常重要,一般情況下我們都是通過擴展這個接口來顯示獲取我們的用戶信息,用戶登錄時傳遞的用戶名和密碼也是通過這里查找出來的用戶名和密碼進行校驗但是真正的校驗不在這里,而是由AuthenticationManager以及AuthenticationProvider負責的,需要強調的是,如果用戶不存在,不應返回NULL,而要拋出異常UsernameNotFoundException。

AuthenticationManager

AuthenticationManager(接口)是認證相關的核心接口,也是發起認證的出發點,因為在實際需求中,我們可能會允許用戶使用用戶名+密碼登錄,同時允許用戶使用郵箱+密碼,手機號碼+密碼登錄,甚至,可能允許用戶使用指紋登錄(還有這樣的操作?沒想到吧),所以說AuthenticationManager一般不直接認證,AuthenticationManager接口的常用實現類ProviderManager 內部會維護一個List<AuthenticationProvider>列表,存放多種認證方式,實際上這是委托者模式的應用(Delegate)。也就是說,核心的認證入口始終只有一個:AuthenticationManager,不同的認證方式:用戶名+密碼(UsernamePasswordAuthenticationToken),郵箱+密碼,手機號碼+密碼登錄則對應了三個AuthenticationProvider。其中有一個重要的實現類是ProviderManager

DaoAuthenticationProvider

AuthenticationProvider最最最常用的一個實現便是DaoAuthenticationProvider。顧名思義,Dao正是數據訪問層的縮寫,也暗示了這個身份認證器的實現思路。主要作用:它獲取用戶提交的用戶名和密碼,比對其正確性,如果正確,返回一個數據庫中的用戶信息(假設用戶信息被保存在數據庫中)。

Securitydemo

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
    public UserDetailsService userDetailsService() {
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        manager.createUser(User.withUsername("xls").password("123").authorities("p1").build());
        manager.createUser(User.withUsername("wxl").password("456").authorities("p2").build());
        return manager;
    }
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }   //注解密碼加密方式

 protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
        .authorizeRequests() //所有請求
                .antMatchers("/r/r1").hasAuthority("p1") //訪問r1需要p1權限
                .antMatchers("/r/r2").hasAuthority("p2") //訪問r2需要p2權限
                .antMatchers("/r/**").authenticated()  //所有/r/**的請求必須認正通過
                .anyRequest().permitAll()//除了/r/**,其他的請求可以訪問
                .and()
                .formLogin() //運行表單登錄
                .loginPage("/loginpage")//登錄頁面訪問地址(可以省略)
                .loginProcessingUrl("/doLogin") //登錄的提交接口 從根目錄開始
                .successForwardUrl("/login-success"); //自定義登錄成功的頁面地址


    }
}
@Service
public class SpringbootUserDetialService implements UserDetailsService {
    @Autowired(required = false)
    private UserMapper mapper;
    @Autowired(required = false)
    private RoleMapper roleMapper;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        com.apesource.springboot_security.doman.User one = mapper.findUserAll(username);
        if (one==null){ //查詢用戶信息
            return null;
        }
//放入權限信息
        String[] rs=new String[one.getRoles().get(0).getPerms().size()];
        Role role = one.getRoles().get(0);
        List<Permission> ps = role.getPerms();
        for (int i = 0; i < ps.size(); i++) {
            rs[i]=ps.get(i).getCode();
        }
        UserDetails user = User.withUsername(one.getUsername()).password(one.getPassword()).authorities(rs).build();
        return user;
    }
}

原文鏈接:https://blog.csdn.net/weixin_71419462/article/details/126691482

欄目分類
最近更新