shiro mysql 密码加密_spring整合shiro(含MD5加密)

shiro简介:

shiro是apache提供的一个强大易用的Java安全框架,用于身份验证、授权、密码学和会话管理。点我下载源码。

开发环境及技术:

1、mysql - 5.7.21

2、navicat(mysql客户端管理工具)

3、eclipse

4、jdk9

5、tomcat 8.5

6、spring & springmvc

7、mybatis 3

8、shiro

9、maven

现在直接开始建项目,从项目中具体讲解shiro的使用,项目虽简单,却五脏俱全。

欢迎大家关注我的公众号 javawebkf,目前正在慢慢地将简书文章搬到公众号,以后简书和公众号文章将同步更新,且简书上的付费文章在公众号上将免费。

一、数据库设计:

数据库有三张表,分别是tb_user用户表,tb_role角色表,tb_permission权限表。

1、tb_user

b12b44219470

图片发自简书App

设置外键rid关联tb_role表

b12b44219470

图片发自简书App

2、tb_role

b12b44219470

图片发自简书App

3、tb_permission

b12b44219470

图片发自简书App

设置外键关联tb_role表

b12b44219470

图片发自简书App

二、项目环境搭建:

1、新建maven web app,结构如下:

b12b44219470

图片发自简书App

2、接下来就是添加依赖:

junit

junit

4.12

test

javax.servlet

javax.servlet-api

3.1.0

javax.servlet.jsp

javax.servlet.jsp-api

2.3.1

javax.servlet

jstl

1.2

org.springframework

spring-core

4.1.7.RELEASE

org.springframework

spring-beans

4.1.7.RELEASE

org.springframework

spring-tx

4.1.7.RELEASE

org.springframework

spring-context

4.1.7.RELEASE

org.springframework

spring-context-support

4.1.7.RELEASE

org.springframework

spring-web

4.1.7.RELEASE

org.springframework

spring-webmvc

4.1.7.RELEASE

org.springframework

spring-aop

4.1.7.RELEASE

org.springframework

spring-aspects

4.1.7.RELEASE

org.springframework

spring-jdbc

4.1.7.RELEASE

org.springframework

spring-test

4.3.14.RELEASE

test

commons-collections

commons-collections

3.2

org.mybatis

mybatis-spring

1.2.3

org.mybatis

mybatis

3.3.0

log4j

log4j

1.2.17

org.slf4j

slf4j-log4j12

1.7.12

mysql

mysql-connector-java

5.1.37

com.mchange

c3p0

0.9.5.2

org.apache.shiro

shiro-core

1.2.4

org.apache.shiro

shiro-web

1.2.4

org.apache.shiro

shiro-spring

1.2.4

依赖对应的作用在代码中有简要的注释。

3、完成配置文件:

在spring文件夹下有:

spring-dao.xml,

spring-mvc.xml,

spring-service.xml,

spring-shiro.xml

①spring-dao.xml

location="classpath:jdbc.properties" />

class="com.mchange.v2.c3p0.ComboPooledDataSource">

class="org.mybatis.spring.SqlSessionFactoryBean">

value="classpath:mappers/*.xml" />

value="classpath:mybatis-config.xml" />

value="sqlSessionFactory">

②spring-service.xml

③spring-mvc.xml

class="org.springframework.web.servlet.view.InternalResourceViewResolver">

class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"

depends-on="lifecycleBeanPostProcessor" />

class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">

注意:开启shiro注解的配置要写在spring-mvc.xml中,具体原因我也不太清楚,有知道的大佬还请留言指教哦!

④spring-shiro.xml

/login=anon

/admin/**=authc,roles[admin]

以下配置文件在resources根目录:

⑤jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver

jdbc.url=jdbc:mysql:///#?useUnicode=true&characterEncoding=utf8

jdbc.username=#

jdbc.password=#

⑥log4j.properties

log4j.rootLogger=DEBUG, Console

#Console

log4j.appender.Console=org.apache.log4j.ConsoleAppender

log4j.appender.Console.layout=org.apache.log4j.PatternLayout

log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n

log4j.logger.java.sql.ResultSet=INFO

log4j.logger.org.apache=INFO

log4j.logger.java.sql.Connection=DEBUG

log4j.logger.java.sql.Statement=DEBUG

log4j.logger.java.sql.PreparedStatement=DEBUG

⑦mybatis-config.xml

/p>

PUBLIC "-//mybatis.org//DTD Config 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-config.dtd">

web.xml在WEB-INF目录下:

⑧web.xml

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee

http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"

version="3.1" metadata-complete="true">

shiroweb

index.jsp

contextConfigLocation

classpath:spring/spring-*.xml

springMVC

org.springframework.web.servlet.DispatcherServlet

contextConfigLocation

classpath:spring/spring-mvc.xml

1

true

springMVC

/

org.springframework.web.context.ContextLoaderListener

shiroFilter

org.springframework.web.filter.DelegatingFilterProxy

targetFilterLifecycle

true

shiroFilter

/*

encodingFilter

org.springframework.web.filter.CharacterEncodingFilter

true

encoding

UTF-8

encodingFilter

/*

至此已完成所有配置,所有的配置文件核心代码都写了注释。

三、项目功能实现

登录验证:

项目功能描述:

在数据库中有两个用户,一个tom,角色为admin,对应的权限有create,delete,query和update,另一个用户cat,角色为guest,权限只有create和query。

1、首先新建User实体类(set、get方法略):

User.java

public class User {

private Integer uid;

private String userName;

private String password;

}

2、dao层的开发

UserDao.java

public interface UserDao {

/**

* 根据用户名查询用户

* @param userName

* @return

*/

public User getByUserName(String userName);

/**

* 根据用户名查询角色

* @param userName

* @return

*/

public Set getRoles(String userName);

/**

* 根据用户名查询权限

* @param userName

* @return

*/

public Set getPermissions(String userName);

}

UserDao.xml

/p>

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

select *

from tb_user

where user_name=#{userName}

select r.role_name

from tb_user u,tb_role r

where u.rid=r.rid

and u.user_name=#{userName}

select p.permission_name

from tb_user u,tb_role r,tb_permission p

where u.rid=r.rid

and p.rid=r.rid

and u.user_name=#{userName}

注意:这里并没有role和permission对应的实体类,也可以新建其对应的实体类,然后把他们设置为User的成员变量,用List集合装载。但是这样做更麻烦一点,因为等下shiro要用到的就是Set集合,如果是List等下还需做转换。

3、dao层测试

写到这可以做一下junit测试,由于篇幅原因,此处不再赘述。

4、service层开发

由于并没有增加逻辑,只是简单调用dao层,所以不再说明。

5、自定义realm

MyRealm.java

public class MyRealm extends AuthorizingRealm {

@Autowired

private UserService userService;

/**

* 为登录用户授予权限和角色

*/

@Override

protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

String userName = (String) principals.getPrimaryPrincipal();

SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();

authorizationInfo.setRoles(userService.getRoles(userName));

authorizationInfo.setStringPermissions(userService.getPermissions(userName));

return authorizationInfo;

}

/**

* 验证当前登录用户

*/

@Override

protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

String userName = (String) token.getPrincipal();

User user = userService.getByUserName(userName);

//使用md5加密

//当前realm对象的name

String realmName = getName();

//盐值

ByteSource credenttialsSalt = ByteSource.Util.bytes(user.getUserName());

//封装用户信息,构建AuthenticationInfo对象并返回

AuthenticationInfo authcInfo = new SimpleAuthenticationInfo(user.getUserName(), user.getPassword(),

credenttialsSalt, realmName);

return authcInfo;

//使用md5加密

//不加密

/*

* if (user != null) {

* AuthenticationInfo authcInfo = new

* SimpleAuthenticationInfo(user.getUserName(), user.getPassword(), "xx");

* return authcInfo;

* } else {

* return null;

* }

*/

//不加密

}

这个类就验证登录和为用户授权两个方法,代码中已有注释说明。若不使用MD5加密,则把我写了MD5加密注释之间那段代码注释掉,把下面注释放开就行;若要使用MD5加密,数据库中的密码也得是加密后的密码可以通过下面的方法获取明文密码对应的密文密码。

获取密文的方法:

public static void main(String[] args) {

String hashAlgorithName = "MD5";

String password = "5678";

int hashIterations = 1024;

ByteSource credentialsSalt = ByteSource.Util.bytes("cat");

Object obj = new SimpleHash(hashAlgorithName, password, credentialsSalt, hashIterations);

System.out.println(obj);

}

6、用户登录的Controller

@Controller

@RequestMapping("/user")

public class UserController {

/**

*

* @param user

* @param request

* @return

*/

@RequestMapping("/login")

public String login(User user,HttpServletRequest request){

//获取当前登录用户

Subject subject=SecurityUtils.getSubject();

//封装表单中提交的用户名和密码

UsernamePasswordToken token=new UsernamePasswordToken(user.getUserName(), user.getPassword());

try{

//调用login方法,传入封装好的token

subject.login(token);

//登录成功跳转success.jsp

return "redirect:/success.jsp";

}catch(Exception e){

e.printStackTrace();

//登录失败就重新登录

request.setAttribute("errorMsg", "登录失败");

return "login";

}

}

}

7、login.jsp

pageEncoding="UTF-8"%>

Insert title here

userName:

password:

${errorMsg }

过程梳理:

在controller中获取到前端表单输入的用户名和密码,封装到token中,然后调用subject的login的方法,传入这个token,这个token就会把数据带到realm中,realm中再调service层查询,根据前端token中携带的用户名去查询数据库中记录,进行密码比对。

这里解释spring-shiro.xml中/login=anon的作用,这行代码的意思就是不拦截登录方法,可以匿名访问。

以上就是验证登录的整个流程。

授权:

需求描述:

1、指定角色:

AdminController只有具有admin角色(tom)才能访问;

GuestController只有具有guest角色(cat)才能访问;

2、指定权限:

PermissionController只有具有create权限(tom和cat)的用户才能访问;

涉及知识点:

1、在spring-shiro.xml中进行授权验证

2、注解方式授权验证

3、jsp中授权验证

4、多级路由匹配规则

正式开始:

1、AdminController.java

@Controller

@RequestMapping("/admin")

public class AdminController {

/**

*

* @param user

* @param request

* @return

*/

@RequestMapping("/test")

public String adminTest() {

//Subject subject = SecurityUtils.getSubject();

//if(subject.hasRole("admin")) {

return "admin";

//}else {

// return "login";

//}

}

}

这个授权验证写在spring-shiro.xml中:/admin/**=authc,roles[admin],这样就表示要有admin这个角色的用户才能访问。同时这个也是双重路由,/admin/**就表示拦截admin开头的路由。

2、GuestController.java

public class GuestController {

@RequiresRoles("guest")

@RequestMapping("/guest")

public String guestTest() {

return "guest";

}

}

这个是使用注解方式进行权限验证的,@RequiresRoles("guest")就表示要有guest这个角色才能访问这个路由。

3、PermissionsController.java

@Controller

public class PermissionsController {

/**

*

* @param user

* @param request

* @return

*/

@RequestMapping("/permissions")

public String permissionTest(){

Subject subject = SecurityUtils.getSubject();

if(subject.isPermitted("create")) {

return "permission";

}else {

return "login";

}

}

}

这个是直接在Controller中获取到登录用户,然后用Subject对象的isPermitted方法就行判断。subject.isPermitted("create")用来判断登录的用户是否有create权限,有就true,没有就是false。

4、接下来看看前端页面:

①success.jsp

登录成功跳转到这个页面

Insert title here

欢迎你!

有admin角色才能访问

有create权限就可以访问

guest才能访问

这里定义了三个链接,分别指向上面那三个controller。

②admin.jsp

pageEncoding="UTF-8"%>

Insert title here

欢迎有admin角色的你!

③guest.jsp

pageEncoding="utf-8"%>

Insert title here

欢迎guest!(只有guest角色登录进来才能显示这段话)

欢迎admin!(只有admin角色登录进来才能显示这段话)

这里就用到了jsp标签形式判断角色,xxx就是用来判断当前用户有没有#角色,有#角色才会显示xxx内容。

注意:使用shiro的jsp标签要在jsp页面中添加

④permission.jsp

pageEncoding="UTF-8"%>

Insert title here

欢迎有你!

只有拥有delete权限的人登录进来才能显示这段话.

这里用到了xxx来判断权限,只有具有#权限的用户才会显示xxx内容。

⑤unauthor.jsp

pageEncoding="utf-8"%>

Insert title here

对不起,你没有操作权限!

点此登录

权限认证失败时跳转到此页面,因为在spring-shiro.xml中配置过。

四、项目测试

1、用tom登录

分析:tom具有admin角色和所有权限,所以success.jsp页面的前两个链接可以访问,且permission.jsp的标签里面的话会显示。第三个链接不能访问,会抛出异常,因为需要guest角色才能访问。

结果:

b12b44219470

图片发自简书App

b12b44219470

图片发自简书App

b12b44219470

图片发自简书App

b12b44219470

图片发自简书App

b12b44219470

图片发自简书App

2、用cat登录

分析:cat具有guest角色和create 以及query权限,所以success.jsp的第一个链接不能访问,会跳转到unauthor.jsp,第二个链接可以访问,但是不能显示标签里面的话,第三个链接可以访问,且能显示里面的话。

结果:

b12b44219470

图片发自简书App

b12b44219470

图片发自简书App

b12b44219470

图片发自简书App

所有结果符合预期,测试通过!

五、知识点补充

1、url匹配规则:

/admin?=authc

表示admin1需要认证,admin2也需要,但是admin不一定,因为问号表示单个字符

/admin*=authc

表示admin1需要认证,admin21需要,admin也需要,*号表示一个或多个字符

/admin/**=authc

可以匹配多路径,比如admin/a/b

2、

Subject对象除了isPermitted("#")判断是否拥有#权限,还有hasRole("#")判断是否有#角色,hasRoles(Arrays.asList("role1","role2"))来判断是否有role1和role2角色。

3、其他注释:

@RequiresAuthentication

表示要验证通过才能被访问

@RequiresGuest

表示之前session中没有被验证过才能访问

@RequiresPermissions("create")

表示有create权限才能访问

@RequiresRoles("admin")

只有admin这个角色才能访问

@RequiresUser

指定用户才能访问

总结:

shiro提供了认证登录,授权,密码加密等功能,方便易用。授权可以在spring-shiro中定义过滤链,可以使用注释,也可以在controller 方法中用Subject对象的方法判断,还可以在jsp中使用标签。

以上内容是个人学习笔记整理,如有错误,欢迎批评指正!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值