您的位置:首页 > 编程语言

shiro的认证代码实现

2017-04-27 11:39 232 查看
首先:回顾一下流程。(前提,我们已经搭建好了spring和shiro集成,可以参考:shiro和spring的集成(详细步骤)

1. 获取当前的 Subject. 调用 SecurityUtils.getSubject();

2. 测试当前的用户是否已经被认证. 即是否已经登录. 调用 Subject 的 isAuthenticated() 

3. 若没有被认证, 则把用户名和密码封装为 UsernamePasswordToken 对象

(对于b/s项目 如何获取用户名和密码)

1). 创建一个表单页面

2). 把请求提交到 SpringMVC 的 Handler

3). 获取用户名和密码. 

4. 执行登录: 调用 Subject 的 login(AuthenticationToken) 方法. 

5. 自定义 Realm 的方法, 从数据库中获取对应的记录, 返回给 Shiro.

1). 实际上需要继承 org.apache.shiro.realm.AuthenticatingRealm 类

2). 实现 doGetAuthenticationInfo(AuthenticationToken) 方法. 

6. 由 shiro 完成对密码的比对. 

具体代码实现流程:

1.首先是shiroHandler 也就是controller 层

package com.atguigu.shiro.handler;

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.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
@RequestMapping("/shiro")
public class shiroHandler {

@RequestMapping("/login")
public String login(@RequestParam("username") String username, @RequestParam("password") String password) {
Subject currentUser = SecurityUtils.getSubject();
if (!currentUser.isAuthenticated()) {
// 把用户名和密码封装为 UsernamePasswordToken 对象
UsernamePasswordToken token = new UsernamePasswordToken(username, password);
// rememberme
token.setRememberMe(true);
try {
// 执行登录.
currentUser.login(token);
}
// 所有认证时异常的父类.
catch (AuthenticationException ae) {
System.out.println("登陆失败:"+ae.getMessage());
}
}
return "redirect:/list.jsp";
}
}


2. ShiroRealm的编写
package com.atguigu.shiro.realms;

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.authc.UsernamePasswordToken;
import org.apache.shiro.realm.AuthenticatingRealm;
import org.apache.shiro.realm.Realm;

public class ShiroRealm extends AuthenticatingRealm {

@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
//1.把AuthenticationToken转换 为 UsernamePasswordToken 的token
UsernamePasswordToken upToken = (UsernamePasswordToken)token;
//2。从UsernamePasswordToken 中 获取 username
String username = upToken.getUsername();
//3. 调用数据库的方法,从数据库中查询username 对应的用户记录
System.out.println("从数据库中查询username的相关信息:"+username);
//4. 若用户不存在, 则可以抛出 UnknownAccountException异常
if("unknown".equals(username)){
throw new UnknownAccountException("用户不存在");
}
//5.根据用户信息的情况, 决定是否需要抛出其他的 AuthenticationException
if("monster".equals(username)){
throw new AuthenticationException("用户被锁定");
}
//6.根据用户的情况,来构建 AuthenticationInfo 对象并返回,通常使用的实现类为: SimpleAuthenticationInfo
//以下信息是从数据库中获取的
//1). principal:认证的实体信息. 可以是username , 也可以是数据表对应的用户的实体类对象
Object principal = username;
//2). credentials : 密码
Object credentials = "123456";
//3) realmName: 当前realm 对象的name.  调用父类的getName() 方法即可.
String realmName = getName();
SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(principal, credentials, realmName);

return info;
}
}


3.login.jsp 页面
<h4>Login Page</h4>
<form action="shiro/login" method="post">
username: <input name="username" type="text"><br>
password: <input name="password" type="text"><br> <input
type="submit" value="提交">
</form>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  shiro认证实现