-
pom.xml
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.31</version>
</dependency>
-
配置信息
shiro.ini
[main]
userRealm=com.lhy.realm.UserRealm
securityManager.realm=$userRealm
log4j.properties
log4j.rootLogger=info,stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d%p[%c]-%m%n
%p:输出日志信息优先级,即DEBUG,INFO,WARN,ERROR,FATAL,
%d: 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyyy-MM-dd HH:mm:ss,SSS},输出类似:2011-10-1822:10:28,921
%r: 输出自应用启动到输出该log信息耗费的毫秒数
%c: 输出日志信息所属的类目,通常就是所在类的全名
%t: 输出产生该日志事件的线程名
%l: 输出日志事件的发生位置,相当于%C.%M(%F:%L)的组合,包括类目名、发生的线程,以及在代码中的行数。
%x: 输出和当前线程相关联的NDC(嵌套诊断环境),尤其用到像java servlets这样的多客户多线程的应用中。
%%: 输出一个"%"字符
%F: 输出日志消息产生时所在的文件名称
%L: 输出代码中的行号
%m: 输出代码中指定的消息,产生的日志具体信息
%n: 输出一个回车换行符,Windows平台为"\r\n",Unix平台为"\n"输出日志信息换行.
-
userRealm的具体实现代码
package cn.com.bochy.realm;
import java.util.ArrayList;
import java.util.List;
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.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
publicclass UserRealmextends AuthorizingRealm{
//realm接口的方法
@Override
public String getName() {
return"userRealm";
}
//完成身份认证并返回认证信息
//如果身份认证失败,返回null
@Override
protected AuthenticationInfodoGetAuthenticationInfo(
AuthenticationToken token)throwsAuthenticationException {
//获取用户输入的用户名
String username =(String)token.getPrincipal();//获取身份信息
System.out.println("username----"+username);
//拿数据和数据库中的查询,假设数据库中的名字为admin
String dbUserName="admin";
if(username==dbUserName){
System.out.println("用户名正确");
}else{
thrownewUnknownAccountException("用户名错误!");
}
//实际开发是调用service根据用户名去数据库查对应的密码
//假设获取的密码是1111
String password ="123456";
//Object principal, Object credentials, String realmName
SimpleAuthenticationInfo info =newSimpleAuthenticationInfo(dbUserName,password,getName());
return info;
}
//授权的信息
@Override
protected AuthorizationInfodoGetAuthorizationInfo(PrincipalCollection principals) {
//主的身份信息
String username = principals.getPrimaryPrincipal().toString();
System.out.println("==========授权验证===========");
System.out.println("username ---"+username);
//根据用户名到数据库查询当前用户对应的权限信息 ---这里模拟
List<String> permissions =newArrayList<String>();
permissions.add("user:add");
permissions.add("user:delete");
permissions.add("user:update");
permissions.add("user:find");
/*
*实现了AuthorizationInfo接口info,内部存的是权限和角色
*/
SimpleAuthorizationInfo info =newSimpleAuthorizationInfo();
//给当前用户分配权限
info.addStringPermissions(permissions);
return info;
}
}
-
测试代码
package cn.com.bochy.realm.test;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
publicclass UserRealmTest {
publicstaticvoid main(String[] args) {
//1,创建SecurityManager工厂 读取shiro配置文件
Factory<org.apache.shiro.mgt.SecurityManager> factory =newIniSecurityManagerFactory("classpath:shiro.ini");
//2 通过securityManager工厂获取SecurityManager实例
org.apache.shiro.mgt.SecurityManagersecurityManager = factory.getInstance();
//3将SecurityManager对象设置到运行环境
SecurityUtils.setSecurityManager(securityManager);
//4通过SecurityUtils获取主体subject
Subject subject = SecurityUtils.getSubject();
try {
//5.假设登录名是zhangsan 密码是1111
UsernamePasswordToken token =newUsernamePasswordToken("admin","123456");
//6,登录,进行用户身验证
subject.login(token);
//通过subject判断用户是否通过验证
if(subject.isAuthenticated()){
System.out.println("用户登录成功!");
}
}catch(UnknownAccountException e) {
// System.out.println("用户名错误!");
e.printStackTrace();
}catch(IncorrectCredentialsException e) {
System.out.println("密码错误!");
e.printStackTrace();
}
System.out.println(subject.isPermitted("user:add"));
System.out.println(subject.isPermittedAll("user:delete"));
System.out.println(subject.isPermittedAll("user:update"));
System.out.println(subject.isPermittedAll("user:query"));
System.out.println(subject.isPermittedAll("user:find"));
//"user:delete","user:update","user:query"));
//7退出
subject.logout();
}
}
-
测试结果
2017-07-0507:08:51,483 INFO [org.apache.shiro.config.IniSecurityManagerFactory] - Realmshave been explicitly set on the SecurityManager instance - auto-setting ofrealms will not occur.
username----admin
用户名正确
2017-07-05 07:08:51,498INFO [org.apache.shiro.session.mgt.AbstractValidatingSessionManager] - Enablingsession validation scheduler...
用户登录成功!
==========授权验证===========
username ---admin
true
==========授权验证===========
username ---admin
true
==========授权验证===========
username ---admin
true
==========授权验证===========
username ---admin
false
==========授权验证===========
username ---admin
true