shiro的基础

shiro的基础概念:

shiro的作用:

这里写图片描述

运行的原理:

这里写图片描述

身份验证

这里写图片描述

授权

这里写图片描述
这里写图片描述
这里写图片描述

Security Manager


Shiro是从根对象Security Manager进行身份验证和授权


    纯Java代码写法


    DefaultSecurityManager securityManager = new DefaultSecurityManager();  
    //设置authenticator  
    ModularRealmAuthenticator authenticator = new ModularRealmAuthenticator();  
    authenticator.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy());  
    securityManager.setAuthenticator(authenticator);  

    //设置authorizer  
    ModularRealmAuthorizer authorizer = new ModularRealmAuthorizer();  
    authorizer.setPermissionResolver(new WildcardPermissionResolver());  
    securityManager.setAuthorizer(authorizer);  

    //设置Realm  
    DruidDataSource ds = new DruidDataSource();  
    ds.setDriverClassName("com.mysql.jdbc.Driver");  
    ds.setUrl("jdbc:mysql://localhost:3306/shiro");  
    ds.setUsername("root");  
    ds.setPassword("");  

    JdbcRealm jdbcRealm = new JdbcRealm();  
    jdbcRealm.setDataSource(ds);  
    jdbcRealm.setPermissionsLookupEnabled(true);  
    securityManager.setRealms(Arrays.asList((Realm) jdbcRealm));  

    //将SecurityManager设置到SecurityUtils 方便全局使用  
    SecurityUtils.setSecurityManager(securityManager);  

    Subject subject = SecurityUtils.getSubject();  
    UsernamePasswordToken token = new UsernamePasswordToken("zhang", "123");  
    subject.login(token);  
    Assert.assertTrue(subject.isAuthenticated());  

上面等价于下面的INI配置


    [main]  
    #authenticator  
    authenticator=org.apache.shiro.authc.pam.ModularRealmAuthenticator  
    authenticationStrategy=org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy  
    authenticator.authenticationStrategy=$authenticationStrategy  
    securityManager.authenticator=$authenticator  

    #authorizer  
    authorizer=org.apache.shiro.authz.ModularRealmAuthorizer  
    permissionResolver=org.apache.shiro.authz.permission.WildcardPermissionResolver  
    authorizer.permissionResolver=$permissionResolver  
    securityManager.authorizer=$authorizer  

    #realm  
    dataSource=com.alibaba.druid.pool.DruidDataSource  
    dataSource.driverClassName=com.mysql.jdbc.Driver  
    dataSource.url=jdbc:mysql://localhost:3306/shiro  
    dataSource.username=root  
    #dataSource.password=  
    jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm  
    jdbcRealm.dataSource=$dataSource  
    jdbcRealm.permissionsLookupEnabled=true  

INI配置

ini配置文件类似于Java中的properties(key=value),不过提供了将key/value分类的特性,key是每个部分不重复即可,而不是整个配置文件。如下是INI配置分类:

[main]  
    #提供了对根对象securityManager及其依赖的配置  
    securityManager=org.apache.shiro.mgt.DefaultSecurityManager  
    …………  
    securityManager.realms=$jdbcRealm  

    [users]  
    #提供了对用户/密码及其角色的配置,用户名=密码,角色1,角色2  
    username=password,role1,role2  

    [roles]  
    #提供了角色及权限之间关系的配置,角色=权限1,权限2  
    role1=permission1,permission2  

    [urls]  
    #用于web,提供了对web url拦截相关的配置,url=拦截器[参数],拦截器  
    /index.html = anon  
    /admin/** = authc, roles[admin], perms["permission1"]  

Realm的使用

AuthorizingRealm

public class UserRealm extends AuthorizingRealm {  
    private UserService userService = new UserServiceImpl();  
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {  
        String username = (String)principals.getPrimaryPrincipal();  
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();  
        authorizationInfo.setRoles(userService.findRoles(username));  
        authorizationInfo.setStringPermissions(userService.findPermissions(username));  
        return authorizationInfo;  
    }  
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {  
        String username = (String)token.getPrincipal();  
        User user = userService.findByUsername(username);  
        if(user == null) {  
            throw new UnknownAccountException();//没找到帐号  
        }  
        if(Boolean.TRUE.equals(user.getLocked())) {  
            throw new LockedAccountException(); //帐号锁定  
        }  
        //交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配,如果觉得人家的不好可以在此判断或自定义实现  
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(  
                user.getUsername(), //用户名  
                user.getPassword(), //密码  
                ByteSource.Util.bytes(user.getCredentialsSalt()),//salt=username+salt  
                getName()  //realm name  
        );  
        return authenticationInfo;  
    }  
}   

UserRealm父类AuthorizingRealm将获取Subject相关信息分成两步:获取身份验证信息(doGetAuthenticationInfo)及授权信息(doGetAuthorizationInfo);

AuthenticationToken

这里写图片描述
AuthenticationToken用于收集用户提交的身份(如用户名)及凭据(如密码):

public interface AuthenticationToken extends Serializable {  
    Object getPrincipal(); //身份  
    Object getCredentials(); //凭据  
}   

扩展接口RememberMeAuthenticationToken:提供了“boolean isRememberMe()”现“记住我”的功能;
扩展接口是HostAuthenticationToken:提供了“String getHost()”方法用于获取用户“主机”的功能。

AuthenticationInfo

这里写图片描述

AuthorizationInfo

这里写图片描述

Subject

这里写图片描述
这里写图片描述
这里写图片描述

PrincipalCollection

这里写图片描述

拓展

虚线表示的是:

依赖关系有如下三种情况:

1、A类是B类中的(某中方法的)局部变量;

2、A类是B类方法当中的一个参数;

3、A类向B类发送消息,从而影响B类发生变化;

泛化关系:->实线

A是B和C的父类,B,C具有公共类(父类)A,说明A是B,C的一般化(概括,也称泛化)

发布了45 篇原创文章 · 获赞 28 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_15006743/article/details/76273530