shiro安全框架+密码加密器

编程入门 行业动态 更新时间:2024-10-19 10:20:36

shiro安全<a href=https://www.elefans.com/category/jswz/34/1770644.html style=框架+密码加密器"/>

shiro安全框架+密码加密器

1、什么是shiro

Apache Shiro™ is a powerful and easy-to-use Java security framework that performs authentication, authorization, cryptography, and session management. With Shiro’s easy-to-understand API, you can quickly and easily secure any application – from the smallest mobile applications to the largest web and enterprise applications.


Apache Shiro 是一个强大易用的 Java 安全框架,提供了认证、授权、加密和会话管理等功能,对于任何一个应用程序,Shiro 都可以提供全面的安全管理服务。并且相对于其他安全框架spring security,Shiro 要简单的多.

 Shiro是apache旗下一个开源框架,它将软件系统的安全认证相关的功能抽取出来,实现用户身份认证,权限授权、加密、会话管理等功能,组成了一个通用的安全认证框架。

1.2 为什么学shiro--简单--安全

Shiro可以非常容易的开发出足够好的应用,其不仅可以用在JavaSE环境,也可以用在JavaEE环境。Shiro可以帮助我们完成:认证、授权、加密、会话管理、与Web集成、缓存等。

1.3 shiro的核心组件

  • Subject

Subject主体,外部应用与subject进行交互,subject将用户作为当前操作的主体,这个主体:可以是一个通过浏览器请求的用户,也可能是一个运行的程序。Subject在shiro中是一个接口,接口中定义了很多认证授相关的方法,外部程序通过subject进行认证授,而subject是通过SecurityManager安全管理器进行认证授权

  • SecurityManager

SecurityManager权限管理器,它是shiro的核心,负责对所有的subject进行安全管理。通过SecurityManager可以完成subject的认证、授权等,SecurityManager是通过Authenticator进行认证,通过Authorizer进行授权,通过SessionManager进行会话管理等。SecurityManager是一个接口,继承了Authenticator, 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存储到缓存服务器redis

  • CacheManager

CacheManager缓存管理,将用户权限数据存储在缓存,这样可以提高性能

  • Cryptography

Cryptography密码管理,shiro提供了一套加密/解密的组件,方便开发。比如提供常用的散列、md5等功能

1.4 使用shiro完成认证-ini

用户的信息存在--ini文件【实际开发存储数据库】。

(1)创建java的maven工程并引入shiro依赖

<dependencies>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <version>1.7.0</version>
        </dependency>
    </dependencies>

(2)创建一个ini文件

# [users]定义用户的信息--当对于表名叫users
[users]
# =左边表示用户名  =右边表示密码
zhangsan=123456
lisi=123456

(3)编写代码

public class ShiroTest {public static void main(String[] args) {DefaultSecurityManager securityManager = new DefaultSecurityManager();IniRealm realm = new IniRealm("classpath:shiro.ini");securityManager.setRealm(realm);SecurityUtils.setSecurityManager(securityManager);Subject subject = SecurityUtils.getSubject();UsernamePasswordToken token = new UsernamePasswordToken("yhl","123456");try{subject.login(token);System.out.println("登陆成功");}catch (Exception e){e.printStackTrace();System.out.println("登陆失败");}}
}

流程图:

1.5 使用shiro完成授权功能--ini

一定是认证后才能对权限判断  

(1)修改ini文件

[users]
yhl=123456,admin
ljh=123456,role1[roles]
admin=user:query,user:update,user:delete,user:insert
role1=user:export,user:delete

 (2)修改代码

public class ShiroTest02 {public static void main(String[] args) {DefaultSecurityManager securityManager = new DefaultSecurityManager();IniRealm realm = new IniRealm("classpath:shiro.ini");securityManager.setRealm(realm);//指定realmSecurityUtils.setSecurityManager(securityManager);//连接上下文,不然不生效Subject subject = SecurityUtils.getSubject();UsernamePasswordToken token = new UsernamePasswordToken("ljh","123456");try {subject.login(token);System.out.println("登陆成功");}catch (Exception e){e.printStackTrace();System.out.println("登陆失败");}
//        subject.logout();//退出之后就查询不到权限了System.out.println("---------------------------");boolean permittedAll = subject.isPermittedAll("user:export", "user:delete");//是否同时具有所有的权限System.out.println("是否同时具有所有的权限:" + permittedAll);boolean[] permitted = subject.isPermitted("user:export", "user:delete", "user:query", "user:insert");System.out.println("判断用户具有的权限:" + Arrays.toString(permitted));boolean b = subject.isPermitted("user:query");System.out.println("判断用户是否具有query:" + b);}
}

流程图:  

1.6 使用shiro完成认证--数据源

上面我们通过读取 ini 文件,可以获取数据源。 IniRealm 完成的读取并授权。而现在如果要读取数据源的数据完成认证授权,则需要自定义realm 类。 自己在service中造了一些数据!!!! 

 (1)引入依赖

<dependencies><dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-core</artifactId><version>1.7.0</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.28</version></dependency><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>22.0</version></dependency></dependencies>

 并且创建实体类~!

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {private Integer id;private String username;private String password;private String address;}

(2)创建一个MyRealm类并继承AuthorizingRealm

public class MyRealm extends AuthorizingRealm {private UserServiceImpl userService=new UserServiceImpl();@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {System.out.println("执行了授权方法----------------------");//通过getPrimaryPrincipal可以获得传过来的信息String primaryPrincipal = principalCollection.getPrimaryPrincipal().toString();System.out.println(primaryPrincipal);//通过查询出来的权限放到一个List集合中List<String> list = userService.findByUsername(primaryPrincipal);//判断list的长度判断是否有权限if (list.size()!=0){SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();//将数据封装到SimpleAuthenticationInfo里面info.addStringPermissions(list);return info;}return null;}@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {System.out.println("执行了认证方法----------------------");String username = authenticationToken.getPrincipal().toString();//获取当前登陆的用户名User user = userService.findUsername(username);if (user!=null){//将数据封装到SimpleAuthenticationInfo里面SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username,user.getPassword(),this.getName());return info;}return null;}
}
(3)UserService 类
public class UserServiceImpl {public User findUsername(String username){if ("yhl".equals(username)){return new User(1,"yhl","123456","北京");}else if ("ljh".equals(username)){return new User(1,"ljh","123","上海");}return null;}public List<String> findByUsername(String username) {//自己添加一些数据让service查出来,看看效果ArrayList<String> list = new ArrayList<>();if ("yhl".equals(username)){list.add("user:query");list.add("user:delete");list.add("user:insert");list.add("user:update");}else if ("ljh".equals(username)){list.add("user:export");list.add("user:delete");}return list;}
}

(4)测试类

public class Test01 {public static void main(String[] args) {DefaultSecurityManager securityManager = new DefaultSecurityManager();MyRealm myRealm = new MyRealm();//使用自己定义的RealmsecurityManager.setRealm(myRealm);SecurityUtils.setSecurityManager(securityManager);Subject subject = SecurityUtils.getSubject();UsernamePasswordToken token = new UsernamePasswordToken("yhl","123456");try{subject.login(token);//不管有没有登陆成功都会执行认证方法的System.out.println("登陆成功");}catch (Exception e){System.out.println("登陆失败");}boolean permitted = subject.isPermitted("user:query");//登陆成功后才会执行授权方法System.out.println("yhl是否具有query:" + permitted);}
}

2、密码加密器

在数据库中存储的密码是一个密文。

shiro帮我们提供很多种加密器。---如果没有指定加密器,那么都使用默认的无加密器。

public class Test {public static void main(String[] args) {
//        Md5Hash md5Hash1=new Md5Hash("123456");
//        System.out.println(md5Hash1); //别人会把一些场景的明文加密后的密文存储的一个很大的数据库。
//        Md5Hash md5Hash2=new Md5Hash("123456","aaa"); //盐
//        System.out.println(md5Hash2);
//        Md5Hash md5Hash=new Md5Hash("123456","aaa",3);//3:表示加密次数
//        System.out.println(md5Hash);SimpleHash simpleHash=new SimpleHash("SHA","123456","aaa",1024);SimpleHash simpleHash2=new SimpleHash("MD5","123456","aaa",1024);System.out.println(simpleHash);System.out.println(simpleHash2);}
}

2.2 把密码匹配器使用在shiro

(1)修改userService中的代码

(2)修改测试代码

 (3)myRealm代码

 

 

更多推荐

shiro安全框架+密码加密器

本文发布于:2024-03-10 13:30:58,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1728106.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:框架   加密器   密码   shiro

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!