最近在重构,有空学了一个简单的安全框架shiro,资料比较少,在百度和google上能搜到的中文我看过了,剩下的时间有空会研究下官网的文章和查看下源码,
简单的分享一些学习过程;
1,简单的一些概念上的认知
2,使用认证的基本流程
3,shiro集成spring完成简单的认证流程,已实现
| 1 |
建一个maven的web项目,引入依赖
springmvc的的依赖
org.springframework
spring-webmvc
3.2.0.RELEASE
shiro跟spring集成的插件
org.apache.shiro
shiro-spring
1.2.3
|
| 2 |
配置web.xml 指出spring容器的配置文件位置
contextConfigLocation
classpath*:context_config.xml
指出spring在web容器中的代号
webAppRootKey
wechatSystem
初始化spring的容器
org.springframework.web.context.ContextLoaderListener
spring mvc的分发器
admin
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath*:admin-dispatcher-servlet.xml
1
admin
/
spring跟shiro集成的过滤代理
shiroFilter
org.springframework.web.filter.DelegatingFilterProxy
targetFilterLifecycle
true
shiroFilter
/admin/*
characterEncoding
org.springframework.web.filter.CharacterEncodingFilter
encoding
UTF-8
forceEncoding
true
characterEncoding
/*
|
| 3 |
配置shiroFilter实例
/admin/login=anon
/admin/validCode=anon
/user/**=authc
/role/**=authc
/permission/**=authc
/**=authc
|
| 4 |
开发跟shiro交互的RealM,一般把权限信息放到db中
package com.util;
import com.domain.User;
import com.domain.UserDto;
import com.google.common.base.Strings;
import com.service.UserDtoService;
import com.service.UserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.jdbc.JdbcRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* User: cutter.li
* Date: 2014/6/19 0019
* Time: 15:24
* 备注: 自定义的mysql数据源
*/
@Component
public class MysqlJdbcRealM extends JdbcRealm {
@Resource
private UserService userService;
//登录认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
String username = String.valueOf(usernamePasswordToken.getUsername());
User user = userService.findByUserName(username);
AuthenticationInfo authenticationInfo = null;
if (null != user) {
String password = new String(usernamePasswordToken.getPassword());
if (password.equals(user.getPassword())) {
authenticationInfo = new SimpleAuthenticationInfo(user.getUsername(), user.getPassword(), getName());
}
}
return authenticationInfo;
}
//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String username = (String) principals.getPrimaryPrincipal();
if (!Strings.isNullOrEmpty(username)) {
SimpleAuthorizationInfo authenticationInfo = new SimpleAuthorizationInfo();
authenticationInfo.setRoles(userService.findRolesStr(username));
authenticationInfo.setStringPermissions(userService.findPermissionsStr(username));
return authenticationInfo;
}
return null;
}
} |
|
| 5 |
简单的登录页面,功能测试
|
| 6 |
controller的实现:
@RequestMapping(value = "login", method = RequestMethod.POST)
public ResponseEntity loginSubmit(String username, String password, String vcode, HttpServletRequest request) {
message.setSuccess();
validateLogin(message, username, password, vcode);
try {
// String code = request.getSession().getAttribute(AppConstant.KAPTCHA_SESSION_KEY).toString();
// if (!vcode.equalsIgnoreCase(code)) {
// message.setCode(AppConstant.VALIDCODE_ERROR);
// message.setMsg("验证码错误");
// }
if (message.isSuccess()) {
Subject subject = SecurityUtils.getSubject();
subject.login(new UsernamePasswordToken(username, password));
if (subject.isAuthenticated()) {
message.setMsg("登录成功");
} else {
message.setCode(AppConstant.USERNAME_NOTEXIST);
message.setMsg("用户名/密码错误");
}
}
}catch (AuthenticationException ex){
message.setCode(AppConstant.USERNAME_NOTEXIST);
message.setMsg("用户名/密码错误");
ex.printStackTrace();
}
finally {
return new ResponseEntity(message, HttpStatus.OK);
}
} |
|
| 7 |
指定认证的策略和多数据源
/admin/login=anon
/admin/validCode=anon
/user/**=authc
/role/**=authc
/permission/**=authc
/**=authc
|