首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Web应用程序Apache集成

Web应用程序Apache集成
EN

Stack Overflow用户
提问于 2015-03-12 19:23:42
回答 1查看 1.7K关注 0票数 0

我正在尝试理解Apache工作流,以及如何将它集成到我的应用程序中。我无法理解的是,如何在何处执行登录,然后发送重定向?或者Shiro会自动这样做(因为我在ini文件中指定了领域)?我可以发送自定义信息(用户属性)以及重定向(通过Servlet响应而不是支持bean)吗?

到目前为止我所理解和拥有的:

将Shiro侦听器和过滤器添加到web.xml文件中,以便它能够响应请求:

代码语言:javascript
复制
<listener>
    <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
</listener>

<filter>
    <filter-name>ShiroFilter</filter-name>
    <filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>ShiroFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>ERROR</dispatcher>
</filter-mapping>

创建一个shiro.ini文件,在该文件中可以为Shiro配置一些属性:

代码语言:javascript
复制
[main]
shiro.loginURL = /login.xhtml
myRealm = com.example.shiro.MyRealm
securityManager.realms = $myRealm

[urls]
/account/** = authc
/logout = logout

创建自定义领域类:

代码语言:javascript
复制
@Stateless
@Local(Realm.class)
public class SecurityBean implements Realm{
    private EntityManager em;
    private TypedQuery<Credential> cQuery;

    @Override
    public Account getAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        try{
            cQuery = em.createNamedQuery("getCredentials", Credential.class);
            cQuery.setParameter("userName", ((UsernamePasswordToken) token).getUsername());
            Credential c = cQuery.getSingleResult();
            boolean b = Encryption.compare(new String(((UsernamePasswordToken) token).getPassword()), c.getSalt(), c.getEncryptedPassword());
            if(b){
                return c;
            }else{
                throw new AuthenticationException("Passwords do not match.");
            }
        }catch(Exception e){
            throw new AuthenticationException("Error verifying credentials.");
        }
    }

    @Override
    public String getName() {
        return "User Realm";
    }

    @Override
    public boolean supports(AuthenticationToken token) {
        if(token instanceof UsernamePasswordToken){
            return true;
        }else{
            return false;
        }
    }
}

其中,加密是要加密和比较密码的类,而凭据是存储用户名和密码的JPA实体类:

代码语言:javascript
复制
@NamedQueries({@NamedQuery(name = "getCredentials", query = "SELECT c FROM Credential c WHERE c.userName = :userName"),
            @NamedQuery(name = "deleteCredentials", query = "DELETE FROM Credential c WHERE c.userName = :userName")})
@Entity
public class Credential implements Serializable, Account{
    private static final long serialVersionUID = 2555682746921997545L;

    @Id @GeneratedValue
    private long id;

    private String userName;

    private String encryptedPassword;
    private String salt;

    private User user;

    //... getters/setters...
}

其中,用户是实际存储用户应用程序信息的JPA实体类。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-03-18 15:01:41

Shiro将自动拦截对受限资源的任何请求,并显示已定义的登录屏幕。您只需要声明应用程序资源所需的身份验证级别。接受你的代码:

代码语言:javascript
复制
[main]
shiro.loginURL = /login.xhtml
myRealm = com.example.shiro.MyRealm
securityManager.realms = $myRealm

[urls]
/account/** = authc
/logout = logout

你跟Shiro说:

  1. 要显示给用户的登录屏幕是/login.xhtml
  2. 您的领域类是com.example.shiro.MyRealm。Shiro将实例化它,并将特定于应用程序的安全操作委托给它。这里是您可以编写特定安全代码的地方。如果我不理解错误,您的SecurityBean就是您的自定义Realm,因此应该将它重命名为com.example.shiro.MyRealm,或者将myRealm更改为指向该类。
  3. /account/** = authc/account/中的每个资源都需要对用户进行身份验证。因此,如果用户尚未通过身份验证,任何尝试都将导致Shiro显示登录页面。
  4. 当用户转到/logout时,shiro将结束会话

我看到的是,您在[urls]部分的开头缺少了这一行:/login.xhtml = authc/login.xhtml不限于经过身份验证的用户(否则没有人可以登录),但必须为其指定authc筛选器,以便它能够处理url的登录提交。它非常“聪明”,可以像上面shiro.loginUrl所指定的那样允许这些请求通过。

顺便说一句,如果您还想拥有一个完整的用户管理解决方案,请看一看风暴路径。我们还有一个与Shiro无缝工作的插件。您可以看看我们的示例风暴路径Shiro应用程序

免责声明,我是一个积极的风暴路径贡献者。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29018542

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档