前面一个小节完成基本的配置,后面一个小节重点放在认证(登陆)和授权
- UserHandler.java
package cn.zzu.wcj.shiro.handler;
import javax.servlet.http.HttpSession;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import cn.zzu.wcj.shiro.service.ShiroService;
@Controller
@RequestMapping("/Shiro")
public class UserHandler {
@Autowired
private ShiroService shiroService ;
@RequestMapping("doLogin")
public String doLogin(@RequestParam String userName,@RequestParam String password){
Subject currentUser = SecurityUtils.getSubject();
System.out.println(userName+"###############"+password);
if (!currentUser.isAuthenticated()) {
//把用户账号和密码封装成令牌
UsernamePasswordToken token = new UsernamePasswordToken(userName, password);
System.out.println("############1.Token"+token.hashCode());
//设置记住我
token.setRememberMe(true);
try {
//执行登陆
currentUser.login(token);
//若账户不存在,则Shiro会抛出UnknownAccountException异常
} catch (UnknownAccountException uae) {
System.out.println("##############用户名错误!"+uae);
//若账户存在,但密码不存在,则抛出IncorrectCredentialsException异常
} catch (IncorrectCredentialsException ice) {
System.out.println("##############密码错误!"+ice);
//若账户被锁定,就抛出LockedAccountException异常
} catch (LockedAccountException lae) {
System.out.println("##############账户锁定!"+lae);
//所有认证时异常的父类
}catch (AuthenticationException ae) {
System.out.println("##############登陆错误!"+ae);
}catch(Exception e){
System.out.println("##################"+e);
}
}
return "redirect:/list.jsp" ;
}
@RequestMapping("/testAnno")
public String testAnno(HttpSession session){
session.setAttribute("wcj","java");
this.shiroService.sayHello();
return "redirect:/list.jsp" ;
}
}
- ShiroRealm.java
package cn.zzu.wcj.shiro.realm;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
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.apache.shiro.util.ByteSource;
public class ShiroRealm extends AuthorizingRealm {
/**
* @see 授权会被 shiro 回调的方法
*/
@Override
protected AuthorizationInfo doGetAuthorizationInfo(
PrincipalCollection principals) {
System.out.println("#################################################授权回调");
//1. 从 PrincipalCollection 中来获取登录用户的信息
Object userName=principals.getPrimaryPrincipal() ;
//2. 利用登录的用户的信息来用户当前用户的角色或权限(可能需要查询数据库)
Set<String> roles=new HashSet<String>() ;
roles.addAll(Arrays.asList("user")) ;
//3. 创建 SimpleAuthorizationInfo, 并设置其 reles 属性.
SimpleAuthorizationInfo info=new SimpleAuthorizationInfo(roles) ;
return info ;
}
/**
* @see 此方法是用来完成认证(即登陆功能的)
*/
@Override
protected AuthenticationInfo doGetAuthenticationInfo(
AuthenticationToken token) throws AuthenticationException {
System.out.println("############[UsernamePasswordRealm]2.Token"+token);
SimpleAuthenticationInfo authcInfo=null ;
//1.将AuthenticationToken强转成UsernamePasswordToken
UsernamePasswordToken upToken=(UsernamePasswordToken) token;
//2.获取用户名
String userName=upToken.getUsername() ;
//3.与数据库中用户名进行比对
if("unknow".equals(userName)){
throw new UnknownAccountException("用户名不存在") ; //抛出用户名错误异常
}
if("ghost".equals(userName)){
throw new LockedAccountException("用户被锁定") ;
}
//4.将数据库中查询到的用户名和密码放置到SimpleAuthenticationInfo中
//1)Object principal 用户认证信息,即用户名,
//2)Object credentials 用户密码,
//3)String realmName Real名称,通过getName取得
Object principal="admin" ;
Object credentials="02bad5ac06ea6ce0be3a24fd39781d11" ;
String realmName=super.getName() ; //调用父类获取Realm名称的方法
ByteSource credentialsSalt=ByteSource.Util.bytes(userName); //盐值加密
authcInfo=new SimpleAuthenticationInfo(principal, credentials, credentialsSalt, realmName);
return authcInfo;
}
}
- ShiroService.java
package cn.zzu.wcj.shiro.service;
import java.util.Date;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.session.Session;
import org.springframework.stereotype.Service;
@Service
public class ShiroService {
@RequiresRoles(value={"admin","user"},logical=Logical.OR)
public void sayHello(){
System.out.println("Hello World !!! "+new Date());
Session session = SecurityUtils.getSubject().getSession();
System.out.println("############wcj-->"+session.getAttribute("wcj"));
}
}
Tips:上面的这些代码看懂了就可以快速搭建Shiro安全框架,你看不懂并不代表我看不懂,我粘贴一下就可以在项目中跑起来,OK?想学习就不要浮躁