首先在进行这个简单的登录认证之前,要先配好ssm+shiro的集成环境。
1.编写用于登录的jsp页面,login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h4>Login page</h4>
<h3 style="color: red"> ${msg}</h3>
<form action="${pageContext.request.contextPath}/login" method="post">
username:<input type="text" name="username" >
<br/><br/>
password:<input type="password" name="password">
<br/><br/>
<input type="submit" value="submit">
</form>
</body>
</html>
这边使用一个表单form进行用户名和密码的提交。提交方式为post,处理表单提交的链接是${pageContext.request.contextPath}/login。建议这边使用绝对路径即${pageContext.request.contextPath}。
<h3 style="color:red">${msg}</h3>则用于显示登录的反馈信息,是用户名不存在还是密码错误,或者说登录的过程中发现了一些其它的异常。
2.编写处理${pageContext.request.contextPath}/login请求的控制器和方法
@Controller
public class UserController {
@Autowired
UserService userService;
@RequestMapping("/login")
public String userLogin(@RequestParam(value="username") String username,@RequestParam(value="password") String password,Model model) {
System.out.println("进入controller");
Subject subject=SecurityUtils.getSubject();
UsernamePasswordToken token=new UsernamePasswordToken(username, password);
try {
subject.login(token);
return "list";
} catch (UnknownAccountException e) {
// TODO: handle exception
model.addAttribute("msg", "用户不存在");
return "login";
}catch(IncorrectCredentialsException e) {
model.addAttribute("msg", "密码错误");
return "login";
}catch(AuthenticationException e) {
model.addAttribute("msg", "发生异常");
return "login";
}
}
}
userLogin()方法用于处理login请求,它包括三个参数,username,password,以及model。model用于设置msg信息,反馈目标页面。
首先我们要获取一个subject主体对象,SecurityUtils.getSubject()。
接着将参数中的username,password封装成一个token。然后调用subject.login(token)进行登录。subject其实会将login(token)委托给SecurityManager.login()方法。
3.编写Realm类,与数据库底层数据进行比对。
public class UserRealm extends AuthorizingRealm{
@Autowired
private UserService userService;
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException {
// TODO Auto-generated method stub
System.out.println("进入doGet..");
UsernamePasswordToken usernamePasswordToken=(UsernamePasswordToken) arg0;
if(userService.findUserByUsername(usernamePasswordToken.getUsername())==null) {
return null;
}
return new SimpleAuthenticationInfo("", userService.findUserByUsername(usernamePasswordToken.getUsername()).getPassword(), "");
}
}
这边写的UserRealm实现了AuthorizingRealm,实现了它的doGetAuthencicationInfo方法,之前的token会作为此方法的参数,这边通过用户名进行查找,若查找无结果,则表示不存在此用户信息,会抛出UnknownAccountException;若存在此用户,则将密码比对的任务交给SimpleAuthenticationInfo(),若密码错误则会抛出IncorrectCredentialsException。
5.在spring配置文件中得配置Realm.
<bean id="myRealm" class="com.sc.testshiro.realms.UserRealm">
</bean>
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="cacheManager" ref="cacheManager"></property>
<!-- Single realm app. If you have multiple realms, use the 'realms' property instead. -->
<property name="realm" ref="myRealm"/>
<!-- By default the servlet container sessions will be used. Uncomment this line
to use shiro's native sessions (see the JavaDoc for more): -->
<!-- <property name="sessionMode" value="native"/> -->
</bean>
配置完成。