shiro试用记录-FormAuthenticationFilter

  • Post author:
  • Post category:其他


前言

本篇文件主要是把最近试用的shiro的过程记录一下

正文

在shirt中,有很多filter,

FormAuthenticationFilter

就是其中之一。这个Filter不能算是最简单(内部有一些隐含处理),但算是一个标准Filter。使用这个Filter时候的注意点说一下:

shiro.ini

在这个文件中,在配置验证时候,只需要配置以下内容:

[main]
authc.loginUrl=/login
authc.usernameParam=username
authc.passwordParam=password
authc.successUrl=/

不需要配置

authc = org.apache.shiro.web.filter.authc.FormAuthenticationFilter

,因为默认的就是

FormAuthenticationFilter

login方法

在写login方法,要留意两点:

1. 不用像以往的方式去写,例如:

登录成功后,跳到哪个画面;登录不成功,跳到哪个画面

。因为如果登录成功后,会跳到上面ini文件中,

successUrl

指定的地址;如果是访问别的路径时,自动跳转到login画面的话,登录成功后会跳转到之前的那个路径。

2. login方法中,不用像下面那样使用shiro。

//1、获取SecurityManager工厂,此处使用Ini配置文件初始化SecurityManager
Factory<SecurityManager> factory =
        new IniSecurityManagerFactory(configFile);

//2、得到SecurityManager实例 并绑定给SecurityUtils
org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();
SecurityUtils.setSecurityManager(securityManager);

//3、得到Subject及创建用户名/密码身份验证Token(即用户身份/凭证)
Subject subject = SecurityUtils.getSubject();
UsernamePasswordToken token = new UsernamePasswordToken(username, password);

subject.login(token);

上面的代码,在

FormAuthenticationFilter

内部都已经做完了。如果进入到后台的login方法的话,说明验证失败,我们只需要在login方法中写上验证失败的逻辑就好,如下:

@Action("post:/login")
public View loginSubmit(Param param) {
    String errorClassName = (String) ServletHelper.getRequestAttribute(FormAuthenticationFilter.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME);
    if(UnknownAccountException.class.getName().equals(errorClassName)) {
        ServletHelper.setRequestAttribute("error", "用户名/密码错误");
    } else if(IncorrectCredentialsException.class.getName().equals(errorClassName)) {
        ServletHelper.setRequestAttribute("error", "用户名/密码错误");
    } else if(errorClassName != null) {
        ServletHelper.setRequestAttribute("error", "未知错误:" + errorClassName);
    }
    // 登录失败后,跳回到login画面,让用户再次登录
    return new View("login);
}

具体代码如下:

Controller:

package org.smart4j.chapter3.controller;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.smart4j.framework.annotation.Action;
import org.smart4j.framework.annotation.Controller;
import org.smart4j.framework.bean.Param;
import org.smart4j.framework.bean.View;
import org.smart4j.framework.helper.ServletHelper;

/**
 * Created by shijiapeng on 16/12/20.
 */
@Controller
public class SystemController {

    private static final Logger LOGGER = LoggerFactory.getLogger(SystemController.class);

    @Action("get:/")
    public View index() {
        return new View("index.jsp");
    }

    @Action("get:/login")
    public View login() {
        return new View("login.jsp");
    }


    @Action("post:/login")
    public View loginSubmit(Param param) {

        String errorClassName = (String) ServletHelper.getRequestAttribute(FormAuthenticationFilter.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME);
        if(UnknownAccountException.class.getName().equals(errorClassName)) {
            ServletHelper.setRequestAttribute("error", "用户名/密码错误");
        } else if(IncorrectCredentialsException.class.getName().equals(errorClassName)) {
            ServletHelper.setRequestAttribute("error", "用户名/密码错误");
        } else if(errorClassName != null) {
            ServletHelper.setRequestAttribute("error", "未知错误:" + errorClassName);
        }

        return new View("/customer_edit?id=1");
    }

    @Action("get:/logout")
    public View logout() {
        SecurityUtils.getSubject().logout();
        return new View("/login");
    }

}


shirt.ini:

[main]
authc.loginUrl=/login
authc.usernameParam=username
authc.passwordParam=password
authc.successUrl=/customer
#authc = org.apache.shiro.web.filter.authc.FormAuthenticationFilter
#authc = org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter

ds=org.apache.commons.dbcp2.BasicDataSource
ds.driverClassName=com.mysql.jdbc.Driver
ds.url=jdbc:mysql://localhost:3306/Test
ds.username=root
ds.password=root


jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm
jdbcRealm.dataSource=$ds
jdbcRealm.authenticationQuery=SELECT password FROM user WHERE username = ?
jdbcRealm.userRolesQuery=SELECT role_name FROM user u, role r, user_role ur WHERE u.id = ur.user_id AND r.id = ur.role_id AND u.username = ?
jdbcRealm.permissionsQuery=SELECT permission_name FROM permission p, role r, role_permission rp WHERE r.id = rp.role_id AND rp.permission_id = p.id AND r.role_name = ?
jdbcRealm.permissionsLookupEnabled=true
securityManager.realms=$jdbcRealm

[urls]
/*=authc


login.jsp:

<%@ page pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %>

<c:set var="BASE" value="${pageContext.request.contextPath}"/>

<html>
<head>
    <title>登录</title>
</head>
<body>

<h1>登录</h1>

<shiro:guest>
    <form action="${BASE}/login" method="post">
        <table>
            <tr>
                <td>用户名:</td>
                <td><input type="text" name="username"></td>
            </tr>
            <tr>
                <td>密码:</td>
                <td><input type="password" name="password"></td>
            </tr>
            <tr>
                <td colspan="2">
                    <button type="submit">登录</button>
                </td>
            </tr>
        </table>
    </form>
</shiro:guest>

<shiro:user>
    shir:user
    <c:redirect url="${BASE}/customer_edit?id=2"/>

</shiro:user>

</body>
</html>



版权声明:本文为hotdust原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。