NutzCN Logo
问答 nutzbook shiro问题
发布于 2840天前 作者 hanang128 2667 次浏览 复制 上一个帖子 下一个帖子
标签:

按照nutzbook一步步做的,在添加完AuthorityModule后访问http://127.0.0.1:8080/nutz/page/simple_role.jsp,ajax调用
http://127.0.0.1:8080/nutz/admin/authority/users 返回

{ok: false, msg: "user.require.login", type: "user.require.login"}
msg
:
"user.require.login"
ok
:
false
type
:
"user.require.login"

AuthorityModule中的代码如下:

  @At
    @RequiresPermissions("authority:user:query")
    @Ok("json:{locked:'password|salt',ignoreNull:true}")
    public Object users(@Param("query") String query, @Param("..") Pager pager){
        return ajaxOk(query(User.class, Cnd.NEW().asc("id"), pager, null));
    }

已使用admin成功登陆,数据库的权限也都建好了,不知道这是什么原因?

17 回复

debug一下checkBasicRoles方法,看看admin是否拥有全部权限

是的 admin是admin角色,admin角色拥有所有权限。

我去。。。 你这是没登录

@At("/")
    //@RequiresPermissions("user:list")
    @RequiresUser
    @Ok("jsp:jsp/user/list")
    public void index(){

    }

使用@RequiresUser注解的可以正常访问的

如果权限不足,报的是 user.require.auth, 未登陆的话报 user.require.login

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

不知道是哪里错了

shiro插件是最新的吗?

debug一下这个,登录试试,看看是不是真的登录了

SecurityUtils.getSubject().login(new SimpleShiroToken(userId));
            return re.setv("ok",true);

执行了这个类 org.apache.shiro.subject.support.DelegatingSubject 的login方法

public void login(AuthenticationToken token) throws AuthenticationException {
        this.clearRunAsIdentitiesInternal();
        Subject subject = this.securityManager.login(this, token);
        String host = null;
        PrincipalCollection principals;
        if(subject instanceof DelegatingSubject) {
            DelegatingSubject session = (DelegatingSubject)subject;
            principals = session.principals;
            host = session.host;
        } else {
            principals = subject.getPrincipals();
        }

        if(principals != null && !principals.isEmpty()) {
            this.principals = principals;
            this.authenticated = true;
            if(token instanceof HostAuthenticationToken) {
                host = ((HostAuthenticationToken)token).getHost();
            }

            if(host != null) {
                this.host = host;
            }

            Session session2 = subject.getSession(false);
            if(session2 != null) {
                this.session = this.decorate(session2);
            } else {
                this.session = null;
            }

        } else {
            String session1 = "Principals returned from securityManager.login( token ) returned a null or empty value.  This value must be non null and populated with one or more elements.";
            throw new IllegalStateException(session1);
        }
    }

好奇怪,那只能debugy一下NutShiroProcessor了

找到问题了

  @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());
    }

realm里边写错了 应该是 return new SimpleAuthenticationInfo(user.getId(),user.getPassword(),getName());
多谢@wendal

@wendal 请问下这个是在那里返回的{ok: false, msg: "user.require.login", type: "user.require.login"},是shiro带的吗?想自己定义这个j'son格式

NutShiroProcessor里面的

添加回复
请先登陆
回到顶部