Shiro+Mysql进行授权验证
在我们的学习过程中,数据是至关重要的,而且是必不可少的一环。在Shiro的学习中,进过数据库的查询,来进行不同用户的权限限定,是必不可少的。
第一步:数据库设计
第二步:导入依赖
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<!--mysql的依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.43</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.6.RELEASE</version>
第三步:编写Ini文件(shiro-mysql.ini)
[main]
dataSource=org.springframework.jdbc.datasource.DriverManagerDataSource
dataSource.driverClassName=com.mysql.jdbc.Driver
dataSource.url=jdbc:mysql://localhost:3306/shiro-test
dataSource.username=root
dataSource.password=root
jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm
#是否检查权限
jdbcRealm.permissionsLookupEnabled = true
#如果没有密码就不用写
jdbcRealm.dataSource=$dataSource
#重写sql语句
#根据用户名查询密码
jdbcRealm.authenticationQuery = select PASSWORD from SHIRO_USER where USER_NAME = ?
#根据用户名查询出角色
jdbcRealm.userRolesQuery = select ROLE_NAME from SHIRO_USER_ROLE where USER_NAME = ?
#根据角色名查询出权限
jdbcRealm.permissionsQuery = select PERM_NAME from SHIRO_ROLE_PERMISSION where ROLE_NAME = ?
securityManager.realms=$jdbcRealm
第四步:自定义Realm类
package com.day511.demoshiro.test2;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.jdbc.core.JdbcTemplate;
import java.util.List;
public class MyRealm2 extends AuthorizingRealm {
private JdbcTemplate jdbcTemplate;
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
//权限验证调用
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
String sql = "select ROLE_NAME from SHIRO_USER_ROLE where USER_NAME = ?";
String username = (String) principalCollection.getPrimaryPrincipal();
List<String> roles = jdbcTemplate.queryForList(sql,String.class,username);
//将查询结果封装到权限信息里面
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.addRoles(roles);
//返回给shiro
return info;
}
//登陆时调用
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
String sql = "select PASSWORD from SHIRO_USER where USER_NAME = ?";
String username = (String) authenticationToken.getPrincipal();
String password = jdbcTemplate.queryForObject(sql,String.class,username);
//用户名 密码 加密 Realm名字
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(username,password,null,getName());
return info;
}
}
第五步:编写Shiro测试类
第一种:调用shiro-mysql.ini文件
package com.day511.demoshiro.test2;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
public class ShiroTestMysql {
public static void main(String[] args) {
// IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro.ini");
//数据库的ini文件
IniSecurityManagerFactory factory = new IniSecurityManagerFactory("classpath:shiro-mysql.ini");
SecurityManager securityManager = factory.getInstance();
//将securityManager绑定,全局,只用设置一次
SecurityUtils.setSecurityManager(securityManager);
//与当前系统进行交互的对象
Subject subject = SecurityUtils.getSubject();
//用户名 密 码 设置
UsernamePasswordToken token = new UsernamePasswordToken("admin@shiro.com","admin");
//登录是否验证过
//登录test
try {
subject.login(token);
if (subject.isAuthenticated()){
System.out.println("登陆成功");
//判断角色 hasRole判断单个角色 hasRoles判断多个角色
if (subject.hasRole("admin")){
System.out.println("有admin这个角色");
}else {
System.out.println("没有admin这个角色");
}
//判断是否拥有指定的权限 isPermitted判断单个权限 isPermittedAll判断多个权限,只要有一个不满足就直接是false
if (subject.isPermitted("/add.html")){
System.out.println("有add权限");
}else {
System.out.println("没有add权限");
}
if (subject.isPermitted("/del.html")){
System.out.println("有del权限");
}else {
System.out.println("没有del权限");
}
}
}catch (AuthenticationException e){
e.printStackTrace();
System.out.println("用户名或密码错误,登陆失败");
}
}
}
第二种:在代码中将ini文件java代码化
package com.day511.demoshiro.test2;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.pam.AtLeastOneSuccessfulStrategy;
import org.apache.shiro.authc.pam.ModularRealmAuthenticator;
import org.apache.shiro.authz.ModularRealmAuthorizer;
import org.apache.shiro.authz.permission.WildcardPermissionResolver;
import org.apache.shiro.mgt.DefaultSecurityManager;
import org.apache.shiro.subject.Subject;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
/**
* shiro + mysql进行验证
*/
public class ShiroMysqlTest {
public static void main(String[] args) {
//启动ini文件时,自动默认创建一个securityManager对象
DefaultSecurityManager securityManager = new DefaultSecurityManager();
//设置身份验证的策略
ModularRealmAuthenticator authenticator;
authenticator = new ModularRealmAuthenticator();
//至少有一个这样的策略
authenticator.setAuthenticationStrategy(new AtLeastOneSuccessfulStrategy());
//将这个策略指定给securityManager
securityManager.setAuthenticator(authenticator);
//设置授权
ModularRealmAuthorizer authorizer = new ModularRealmAuthorizer();
//用于解析对应的字符串
authorizer.setPermissionResolver(new WildcardPermissionResolver());
//授权
securityManager.setAuthorizer(authorizer);
//ini文件java化
// dataSource=org.springframework.jdbc.datasource.DriverManagerDataSource
// dataSource.driverClassName=com.mysql.jdbc.Driver
// dataSource.url=jdbc:mysql://localhost:3306/shiro-test
// dataSource.username=root
// dataSource.password=root
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/shiro-test");
dataSource.setUsername("root");
dataSource.setPassword("root");
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
MyRealm2 myRealm2 = new MyRealm2();
myRealm2.setJdbcTemplate(jdbcTemplate);
//自定义数据源
securityManager.setRealm(myRealm2);
//绑定上下文
SecurityUtils.setSecurityManager(securityManager);
//与当前系统进行交互的对象
Subject subject = SecurityUtils.getSubject();
//用户名 密 码 设置
UsernamePasswordToken token = new UsernamePasswordToken("admin@shiro.com","admin");
try {
subject.login(token);
System.out.println("登陆成功");
if (subject.isAuthenticated()){
//判断角色 hasRole判断单个角色 hasRoles判断多个角色
if (subject.hasRole("admin")){
System.out.println("有admin这个角色");
}else {
System.out.println("没有admin这个角色");
}
//判断是否拥有指定的权限 isPermitted判断单个权限 isPermittedAll判断多个权限,只要有一个不满足就直接是false
if (subject.isPermitted("/add.html")){
System.out.println("有add权限");
}else {
System.out.println("没有add权限");
}
if (subject.isPermitted("/del.html")){
System.out.println("有del权限");
}else {
System.out.println("没有del权限");
}
}
}catch (AuthenticationException e){
// e.printStackTrace();
System.out.println("用户名或密码错误,登陆失败");
}
}
}