简体   繁体   English

在Grails Spring Security插件中自定义登录

[英]Customize login in Grails Spring Security plugin

I have an application where the login should include an organization number, so the login needs to be username + password + organization number . 我有一个应用程序,该登录名应包含组织号,因此登录应为用户名+密码+组织号

Sample case: If the username + password matches with an existing user, I need to check if that user has the organization id. 示例案例:如果用户名+密码与现有用户匹配,我需要检查该用户是否具有组织ID。 If not, the login should fail. 如果不是,则登录将失败。

I saw that the login form from spring security plugin submits to /app/j_spring_security_check but couldn't find where that is actually implemented. 我看到spring安全插件的登录表单提交到/app/j_spring_security_check但是找不到实际实现的位置。

Also I'm not sure if touching that is the right way of implementing this custom login. 另外,我不确定触摸是否是实现此自定义登录的正确方法。

My question is where / how to customize the login action? 我的问题是在哪里/如何自定义登录操作? (to make it fail on the case I described above). (以使其在上述情况下失败)。

We can do this by overriding the filter UserNamePasswordAuthenticationFilter and provide our custom attemptAuthentication. 我们可以通过覆盖过滤器UserNamePasswordAuthenticationFilter并提供自定义的tryAuthentication来做到这一点。 So, go to DefaultSecurityConfig.groovy file (inside plugins). 因此,转到DefaultSecurityConfig.groovy文件(在插件内部)。 See tree diagram below: 请参见下面的树形图:

  target
      |-work
            |-plugins
                    |-spring-security-core-2.0-RC5
                                          |-conf
                                               |-DefaultSecurityConfig.groovy

In DefaultSecurityConfig.groovy under apf closure we specify filterProcessUrl which we can override in grails application's Config.groovy like we do for other properties (eg rejectIfNoRule) 在apf闭合下的DefaultSecurityConfig.groovy中,我们指定filterProcessUrl,可以像在其他属性中所做的一样在grails应用程序的Config.groovy中覆盖它(例如,ifIfIfNoRule)

grails.plugin.springsecurity.apf.filterProcessesUrl="your url"

Now we understood how it checks for authentication.Let's customise it own way by overriding the method attemptAuthentication of filter named UsernamePasswordAuthenticationFilter . 现在我们了解了它如何检查身份验证。让我们通过重写名为UsernamePasswordAuthenticationFilter的过滤器的tryAuthentication方法来自定义其方式。 For example, see below(also, go through the inline comments added there) 例如,请参见下文(另请参阅此处添加的嵌入式注释)

 package org.springframework.security.web.authentication;

    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import org.springframework.security.authentication.AuthenticationServiceException;
    import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
    import org.springframework.security.core.Authentication;
    import org.springframework.security.core.AuthenticationException;
    import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
    import org.springframework.util.Assert;

    public class CustomUsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter {
        public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "j_username";
        public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "j_password";
        /** @deprecated */
        @Deprecated
        public static final String SPRING_SECURITY_LAST_USERNAME_KEY = "SPRING_SECURITY_LAST_USERNAME";
        private String usernameParameter = "j_username";
        private String passwordParameter = "j_password";
        private String organisationParameter = 'j_organisation'
        private boolean postOnly = true;

        public UsernamePasswordAuthenticationFilter() {
            super("/j_spring_security_check");
        }

        public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
            if(this.postOnly && !request.getMethod().equals("POST")) {
                throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
            } else {
                String username = this.obtainUsername(request);
                String password = this.obtainPassword(request);
                String password = this.obtainOrganisation(request);

              //regular implementation in spring security plugin   /**
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
                this.setDetails(request, authRequest);
                return         this.getAuthenticationManager().authenticate(authRequest);
            }
**/

//Your custom implementation goes here(Authenticate on the basis of organisation as well). Here you need to customise authenticate as per your requirement so that it checks for organisation as well.
        }

       protected String obtainOrganisation(HttpServletRequest request) {
        return request.getParameter(this.organisationParameter);
    }    

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

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

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

        public void setUsernameParameter(String usernameParameter) {
            Assert.hasText(usernameParameter, "Username parameter must not be empty or null");
            this.usernameParameter = usernameParameter;
        }

        public void setPasswordParameter(String passwordParameter) {
            Assert.hasText(passwordParameter, "Password parameter must not be empty or null");
            this.passwordParameter = passwordParameter;
        }

        public void setPostOnly(boolean postOnly) {
            this.postOnly = postOnly;
        }

        public final String getUsernameParameter() {
            return this.usernameParameter;
        }

        public final String getPasswordParameter() {
            return this.passwordParameter;
        }
    }

Hence, it's more of a overriding task in terms of spring security. 因此,就弹簧安全性而言,这更是一项首要任务。

To get more clearer idea about same read this nice link for java and for grails read this 要获取有关同一更加清晰的思路阅读这个漂亮的链接 Java和Grails的阅读

Hope it helps. 希望能帮助到你。

These blogs gives a more detailed idea of the same requirements. 这些博客更详细地介绍了相同的要求。

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

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