userModule的login方法:
@At
@POST
//@Filters // 覆盖UserModule类的@Filter设置,因为登陆可不能要求是个已经登陆的Session
@Ok("json")
public Object login(@Param("username") String username,
@Param("password") String password,
@Param("captcha") String captcha,
@Attr(scope = Scope.SESSION,value ="nutz_captcha")String _captcha,
HttpSession session){
NutMap re = new NutMap();
//校验captcha
boolean correct =Tookit.checkCaptcha(_captcha,captcha);
if(!correct){
return re.setv("ok",false).setv("msg","验证码错误");
}
int userId = userService.fetch(username,password);
if(userId<0){
return re.setv("ok",false).setv("msg","用户名密码错误");
}else{
session.setAttribute("me",userId);
// 完成nutdao_realm后启用.
SecurityUtils.getSubject().login(new SimpleShiroToken(userId));
return re.setv("ok",true);
}
}
realm
package com.celesea.nutzbook.shiro.realm;
import com.celesea.nutzbook.bean.Permission;
import com.celesea.nutzbook.bean.Role;
import com.celesea.nutzbook.bean.User;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.nutz.dao.Dao;
import org.nutz.integration.shiro.SimpleShiroToken;
import org.nutz.mvc.Mvcs;
/**
* Created by hanan on 2017-3-12.
*/
public class SimpleAuthorizingRealm extends AuthorizingRealm {
private Dao dao;// ShiroFilter先于NutFilter初始化化,所以无法使用注入功能
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
if (principalCollection == null){
throw new AuthenticationException("PrincipalCollection method argument cannot be null.");
}
int userId = (Integer) principalCollection.getPrimaryPrincipal();
User user = dao().fetch(User.class,userId);
if(user == null){
return null;
}
if(user.isLocked()){
throw new LockedAccountException("Account ["+user.getName()+"] is locked.");
}
SimpleAuthorizationInfo auth = new SimpleAuthorizationInfo();
user = dao.fetchLinks(user,null);
if(user.getRoles() != null){
dao().fetchLinks(user.getRoles(),null);
for(Role role:user.getRoles()){
auth.addRole(role.getName());
if(role.getPermissions() != null){
for(Permission permission:role.getPermissions()){
auth.addStringPermission(permission.getName());
}
}
}
}
if(user.getPermissions()!= null){
for(Permission permission :user.getPermissions()){
auth.addStringPermission(permission.getName());
}
}
return auth;
}
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
SimpleShiroToken upToken =(SimpleShiroToken) authenticationToken;
User user = dao().fetch(User.class,((Integer) upToken.getPrincipal()).longValue());
if(user == null){
return null;
}
if(user.isLocked()){
throw new LockedAccountException("Account ["+user.getName()+"] is locked.");
}
return new SimpleAuthenticationInfo(user.getName(),user.getPassword(),getName());
}
/**
* 覆盖父类的验证,直接pass. 在shiro内做验证的话, 出错了都不知道哪里错
*/
protected void assertCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) throws AuthenticationException {
}
public SimpleAuthorizingRealm() {
this(null, null);
}
public SimpleAuthorizingRealm(CacheManager cacheManager, CredentialsMatcher matcher) {
super(cacheManager, matcher);
setAuthenticationTokenClass(SimpleShiroToken.class); // 非常非常重要,与SecurityUtils.getSubject().login是对应关系!!!
}
public SimpleAuthorizingRealm(CacheManager cacheManager) {
this(cacheManager, null);
}
public SimpleAuthorizingRealm(CredentialsMatcher matcher) {
this(null, matcher);
}
public Dao dao() {
if (dao == null) {
dao = Mvcs.ctx().getDefaultIoc().get(Dao.class, "dao");
return dao;
}
return dao;
}
public void setDao(Dao dao) {
this.dao = dao;
}
}
shiro.ini
[main]
nutzdao_reaml =com.celesea.nutzbook.shiro.realm.SimpleAuthorizingRealm
authc= org.nutz.integration.shiro.SimpleAuthenticationFilter
authc.loginUrl = /user/login
logout.redirectUrl= /user/login
[urls]
/assets/* =anon
/user/logout =logout
/user/login =anon
/user/error =anon
/user/profile/active/mail =anon
不知道是哪里错了