简体   繁体   English

Spring Security自定义过滤器

[英]Spring Security custom filter

I would like to customize Spring security 3.0.5 and change login URL to be /login instead of /j_spring_security_check. 我想自定义Spring security 3.0.5并将登录URL更改为/ login而不是/ j_spring_security_check。

What I need to do, is to to allow login to "/" directory and to secure "/admin/report.html" page. 我需要做的是允许登录到“/”目录并保护“/admin/report.html”页面。

First of All I create my own filter using tutorial and Spring Security source code: 首先,我使用教程和Spring Security源代码创建自己的过滤器:

public class MyFilter extends AbstractAuthenticationProcessingFilter {
    private static final String DEFAULT_FILTER_PROCESSES_URL = "/login";
    private static final String POST = "POST";
    public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "j_username";
    public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "j_password";
    public static final String SPRING_SECURITY_LAST_USERNAME_KEY = "SPRING_SECURITY_LAST_USERNAME";

    private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY;
    private String passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY;

    protected MyFilter() {
        super(DEFAULT_FILTER_PROCESSES_URL);
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request,
                                                HttpServletResponse response) 
                          throws AuthenticationException, IOException, ServletException {
        String username = obtainUsername(request);
        String password = obtainPassword(request);

        if (username == null) {
            username = "";
        }

        if (password == null) {
            password = "";
        }

        username = username.trim();
        UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
        HttpSession session = request.getSession(false);
        if (session != null || getAllowSessionCreation()) {
            request.getSession().setAttribute(SPRING_SECURITY_LAST_USERNAME_KEY, TextEscapeUtils.escapeEntities(username));
        }
        setDetails(request, authRequest);

        return this.getAuthenticationManager().authenticate(authRequest);
    }

    protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) {
        authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res,
                         FilterChain chain) throws IOException, ServletException {
        final HttpServletRequest request = (HttpServletRequest) req;
        final HttpServletResponse response = (HttpServletResponse) res;
        if (request.getMethod().equals(POST)) {
            // If the incoming request is a POST, then we send it up
            // to the AbstractAuthenticationProcessingFilter.
            super.doFilter(request, response, chain);
        } else {
            // If it's a GET, we ignore this request and send it
            // to the next filter in the chain.  In this case, that
            // pretty much means the request will hit the /login
            // controller which will process the request to show the
            // login page.
            chain.doFilter(request, response);
        }
    }

    protected String obtainUsername(HttpServletRequest request) {
        return request.getParameter(usernameParameter);
    }

    protected String obtainPassword(HttpServletRequest request) {
        return request.getParameter(passwordParameter);
    }
}

after It I'm making the following changes in xml 之后我在xml中进行了以下更改

 <security:http auto-config="true">
        <!--<session-management session-fixation-protection="none"/>-->
        <security:custom-filter ref="myFilter" before="FORM_LOGIN_FILTER"/>
        <security:intercept-url pattern="/admin/login.jsp*" filters="none"/>
        <security:intercept-url pattern="/admin/report.html" access="ROLE_ADMIN"/>
        <security:form-login login-page="/admin/login.jsp" login-processing-url="/login" always-use-default-target="true"/>
        <security:logout logout-url="/logout" logout-success-url="/login.jsp" invalidate-session="true"/>
    </security:http>   
<security:authentication-manager alias="authenticationManager">
  <security:authentication-provider>
    <security:password-encoder hash="md5" />
    <security:user-service>
    <!-- peter/opal -->
      <security:user name="peter" password="22b5c9accc6e1ba628cedc63a72d57f8" authorities="ROLE_ADMIN" />
     </security:user-service>
  </security:authentication-provider>
</security:authentication-manager>
<bean id="myFilter" class="com.vanilla.springMVC.controllers.MyFilter">
<property name="authenticationManager" ref="authenticationManager"/>
</bean>

and then I have JSP with my code. 然后我用我的代码编写JSP。

<form action="../login" method="post">
    <label for="j_username">Username</label>
    <input type="text" name="j_username" id="j_username" />
    <br/>
    <label for="j_password">Password</label>
    <input type="password" name="j_password" id="j_password"/>
    <br/>
    <input type='checkbox' name='_spring_security_remember_me'/> Remember me on this computer.
    <br/>
    <input type="submit" value="Login"/>
</form>

when trying to navigate to /admin/report.html I'm redirected to login page. 当我尝试导航到/admin/report.html时,我被重定向到登录页面。 but after submitting credentials I'm getting: 但在提交凭证后我得到了:

HTTP Status 404 - /SpringMVC/login/

type Status report

message /SpringMVC/login/

description The requested resource (/SpringMVC/login/) is not available.

It looks like I have problem in configuration, but I can't figure it out what causing this. 看起来我的配置有问题,但我无法弄清楚导致这种情况的原因。 Can you help? 你能帮我吗?

I'm about 12 months late on this one, but in order to customise the login URL of the Spring Security form login you don't need to create your own filter. 我迟到了大约12个月,但是为了自定义Spring Security表单登录的登录URL,您不需要创建自己的过滤器。 One of the attributes of the form-login tag allows you to set a custom URL. form-login标签的一个属性允许您设置自定义URL。 In fact, you can also change the default j_username and j_password field names using attributes of the form-login tag. 实际上,您还可以使用form-login标记的属性更改默认的j_username和j_password字段名称。 Here's an example: 这是一个例子:

<form-login login-page="/login" login-processing-url="/login.do" default-target-url="/" always-use-default-target="true" authentication-failure-url="/login?error=1" username-parameter="username" password-parameter="password"/>

I think that @Ischin is correct to wonder about the form action url. 我认为@Ischin对形式动作网址的疑问是正确的。 Try putting in the full path and see if that works. 尝试完整路径,看看是否有效。 If it does, you can work from there to figure out what isn't matching up. 如果是这样,你可以从那里找出什么是不匹配的。

The only other thing I can think of to check is the filter mapping in you web.xml. 我能想到要检查的另一件事是web.xml中的过滤器映射。 Since you are hitting the login page you have this set up, but I would check that you're not only intercepting urls with specific extensions, etc. 由于您正在登录页面,因此您已设置此设置,但我会检查您是否不仅截取具有特定扩展名的网址等。

Also, just as an fyi, if you want the request (once the login form authenticates the user) to go to the secured resource (/admin/report.html in this case) then you should remove the form:login always-use-default-target="true". 此外,就像fyi一样,如果您希望请求(一旦登录表单对用户进行身份验证)转到安全资源(在这种情况下为/admin/report.html),那么您应该删除表单:login always-use-默认目标=“真”。 Setting this flag to true will cause the request to always go to the default target url, which usually isn't what you want. 将此标志设置为true将导致请求始终转到默认目标URL,这通常不是您想要的。 From the spring security docs : 春季安全文档

Maps to the defaultTargetUrl property of UsernamePasswordAuthenticationFilter. 映射到UsernamePasswordAuthenticationFilter的defaultTargetUrl属性。 If not set, the default value is "/" (the application root). 如果未设置,则默认值为“/”(应用程序根目录)。 A user will be taken to this URL after logging in, provided they were not asked to login while attempting to access a secured resource, when they will be taken to the originally requested URL. 登录后,用户将被带到此URL,前提是他们在尝试访问受保护资源时未被要求登录,而这些用户将被带到最初请求的URL。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM