使用 Facebook OAuth 进行 Apache Shiro 身份验证

Posted

技术标签:

【中文标题】使用 Facebook OAuth 进行 Apache Shiro 身份验证【英文标题】:Apache Shiro Authentication with Facebook OAuth 【发布时间】:2014-07-09 15:32:43 【问题描述】:

我一直在使用 Facebook OAuth 验证我在 Shiro 上运行的应用程序。我真的不知道我做错了什么。基本上,我的问题是当我从 Facebook 获得“代码”时。我希望 shiro 使用该代码对其进行身份验证。 这是我的验证码。

FacebookToken token = null;
        try
                org.apache.shiro.subject.Subject currentUser = SecurityUtils.getSubject();
                //currentUser.logout(); 
                //This is done to avoid temporary multiple url hit.., when the user is not logged out

                token = new FacebookToken(code);
                currentUser.login(token);  //returns true if valid 
               result =  true;
            catch (UnknownAccountException uae) 
                log.info("There is no user with username of " + token.getPrincipal());
             catch (IncorrectCredentialsException ice) 
                log.info("Password for account " + token.getPrincipal() + " was incorrect!");
             catch (LockedAccountException lae) 
                log.info("The account for username " + token.getPrincipal() + " is locked.  " +
                        "Please contact your administrator to unlock it.");
            
            // ... catch more exceptions here (maybe custom ones specific to your application?
            catch (AuthenticationException ae) 
                log.info("Authentication exception Here.");
            

这是我的 facebook 令牌类:

public class FacebookToken implements AuthenticationToken 

    private static final long serialVersionUID = 1L;
    private String code;
    public FacebookToken()

    

    public FacebookToken(String code)
        this.code = code;
    

    public Object getCredentials() 

        return null; //Credentials are handled by facebook 
    

    public String getCode() 
        return code;
    

    public void setCode(String code) 
        this.code = code;
    

    public Object getPrincipal() 
        return null; //Not known facebook does the login
    

我拥有扩展授权领域的 facebook 领域。

public class FacebookRealm extends AuthorizingRealm 
    

最后是我的 shiro.ini 文件:

[main]  
#authc.loginUrl = /login
#authc.successUrl  = /hello
#logout.redirectUrl = /hello

# ------------------------  
# Database  

# Own Realm  
jdbcRealm = com.shiro.common.controller.MyCustomRealm
facebookRealm = com.facebook.login.FacebookRealm


# Sha256  
sha256Matcher = org.apache.shiro.authc.credential.Sha256CredentialsMatcher
# base64 encoding, not hex in this example:  
sha256Matcher.storedCredentialsHexEncoded = false  
sha256Matcher.hashIterations = 1024  

#Facebook Credential matcher
fbCredentialsMatcher = com.facebook.login.FacebookCredentialsMatcher 


jdbcRealm.credentialsMatcher = $sha256Matcher
facebookRealm.credentialsMatcher = $fbCredentialsMatcher


# User Query  
# default is "select password from users where username = ?"  
jdbcRealm.authenticationQuery = SELECT password, salt FROM User WHERE email = ?

# permissions  
jdbcRealm.permissionsLookupEnabled = true
jdbcRealm.userRolesQuery = select roleName from UserRole where email = ?
jdbcRealm.permissionsQuery = select permission from RolesPermission where roleName = ?

# Connection   
ds = com.mysql.jdbc.jdbc2.optional.MysqlDataSource
ds.serverName = localhost
ds.user = root
ds.password = root123
ds.databaseName = testdb
jdbcRealm.dataSource=$ds

#authc.usernameParam = email
#authc.passwordParam = password
#authc.failureKeyAttribute = shiroLoginFailure

# Use Built-in Chache Manager
builtInCacheManager = org.apache.shiro.cache.MemoryConstrainedCacheManager
securityManager.cacheManager = $builtInCacheManager

#securityManager.realms = $facebookRealm,$jdbcRealm
securityManager.realms = $facebookRealm


# -----------------------------------------------------------------------------  
[urls]  
#/hello = authc
#/login = authc
#/admin.jsp = authc, perms["admin:access"]

现在我什么时候调试并到达 currentuser.login 方法并进入,它会抛出一个异常说 领域 [FacebookRealm@52039826] 不支持身份验证令牌 [FacebookToken@132d9844]。请确保正确配置了适当的 Realm 实现,或者该领域接受此类型的 AuthenticationToken。

请建议我是否做对了!我是否缺少任何配置或其他任何东西。谢谢!!

【问题讨论】:

【参考方案1】:

您应该使用以下方法扩展您的 FacebookRealm:

@Override
public boolean supports(AuthenticationToken token) 
    return token instanceof FacebookToken;

或将以下行添加到您的 ini:

facebookRealm.authenticationTokenClass=<realpackage>.FacebookToken

【讨论】:

以上是关于使用 Facebook OAuth 进行 Apache Shiro 身份验证的主要内容,如果未能解决你的问题,请参考以下文章

使用 facebook 登录并使用 oauth 2.0 对 REST api 调用进行身份验证

ASP.net core web api:使用 Facebook/Google OAuth 访问令牌进行身份验证

OAuth2“社交登录”流程(允许通过 Facebook/Twitter 进行 OAuth2 身份验证):是不是有任何示例/文献?

oauth 与 facebook

像 Facebook 一样的 OAuth 身份验证

允许用户在 React Native/iOS Facebook OAuth 中进行细粒度的权限审批?