Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么spring使得在spring安全性中使用额外的登录参数变得如此困难_Java_Spring_Spring Mvc_Spring Security - Fatal编程技术网

Java 为什么spring使得在spring安全性中使用额外的登录参数变得如此困难

Java 为什么spring使得在spring安全性中使用额外的登录参数变得如此困难,java,spring,spring-mvc,spring-security,Java,Spring,Spring Mvc,Spring Security,在SpringMVC应用程序中,我需要在登录屏幕上捕获一个额外的“location”参数,并将其用于用户名之外的身份验证。我遇到了一些建议实现这一点的方法,但没有一种是直接的,涉及扩展和/或实现大量的spring类和接口我通过扩展UsernamePasswordAuthenticationFilter并在会话中检索和放置位置参数,以某种方式实现了它 public class CustomAuthenticationFilter extends UsernamePasswordAuthentica

在SpringMVC应用程序中,我需要在登录屏幕上捕获一个额外的“location”参数,并将其用于用户名之外的身份验证。我遇到了一些建议实现这一点的方法,但没有一种是直接的,涉及扩展和/或实现大量的spring类和接口
我通过扩展UsernamePasswordAuthenticationFilter并在会话中检索和放置位置参数,以某种方式实现了它

public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        final Long locationId = Long.parseLong(request.getParameter("locations"));
        request.getSession().setAttribute("LOCATION_ID", locationId);

        return super.attemptAuthentication(request, response); 
    } 
}
这种方法看起来像是一种技巧,似乎不太优雅。最重要的是,由于我现在使用的是自定义AuthenticationFilter,所以我必须通过注入大量依赖项来手动配置此筛选器

@Bean
    public CustomAuthenticationFilter customAuthenticationFilter () {
        CustomAuthenticationFilter filter= new  CustomAuthenticationFilter();
        filter.setRequiresAuthenticationRequestMatcher(
                new AntPathRequestMatcher("/login","POST"));
        filter.setAuthenticationManager(authenticationManagerBean());
        filter.setUsernameParameter("username");
        filter.setPasswordParameter("password");
        filter.setAuthenticationSuccessHandler(simpleUrlAuthenticationSuccessHandler());
        filter.setAuthenticationFailureHandler(simpleUrlAuthenticationFailureHandler());
        filter.setRememberMeServices(persistentTokenBasedRememberMeServices());
        return filter;
    }
最终,捕获位置并在身份验证中使用它是可行的,但如果我想使用“记住我”功能,它会产生新的问题。我在这里解释了这个问题
使用额外的登录参数必须是一项常见要求。Spring框架以可插拔和可扩展而闻名,我希望有一种更用户友好的方式来使用其他参数

任何人都可以建议我一个更好的方法在这里使用额外的参数,并让记住我的工作以及。谢谢

spring security的类真的很复杂

使用AbstractPreAuthenticatedProcessingFilter作为超类。 然后,您可以返回一个对象,而不是中的字符串 getPreAuthenticatedPrincipal getPreAuthenticatedCredentials 在那里,您可以从HttpRequest中读取所需的内容,并返回一个包含所有所需数据的对象(因为您需要它作为主体或凭证,无论位置在何处)。也许您可以为返回类型创建一个简单的类

然后创建org.springframework.security.authentication.AuthenticationProvider的子类 .方法中的公共身份验证(身份验证) 您可以使用authentication.getCredentials()和authentication.getPrincipal()访问AbstractPreAuthenticatedProcessingFilter中返回的对象 使用此功能,您可以创建一个或多个新的SimpleGrantedAuthority(角色),每个角色对应一个用户权限; 最后创建一个 Authentication auth=新建用户名PasswordAuthenticationToken(Authentication.getPrincipal()、Authentication.getCredentials()、GrantedAuthories)
返回。

它是可扩展的,这就是您当前正在做的,扩展非默认行为。如果您需要“记住我”部分中的其他信息,您也需要实现自定义实现。但是,您当前的解决方案是一种黑客攻击,请创建一个自定义的
身份验证
对象,其中包含所需的信息(用户名、pwd和位置),而不是将其填充到会话中。此身份验证将传递给其他需要身份验证的类,包括“记住我”之类的内容。Hello Deinum,您能否提供一些详细信息,说明如何使用身份验证对象实现此功能。您的意思是扩展WebAuthenticationDetails类吗?即使使用WebAuthenticationDetails,如何在UserService中获取对它的引用以检索位置参数?我无法从SecurityContextHolder获取它,因为只有在成功登录后,身份验证对象get才会在那里填充。第二,在“记住我”的情况下,我必须在cookie或persistent_登录表中存储和检索位置。我不确定WebAuthenticationDetails如何在那里发挥作用。不知道如何创建自己的
身份验证
,而不是试图将其固定到默认的
用户名密码身份验证
您有不同的要求,然后正确地实现它,而不是在其他东西的基础上进行黑客攻击。感谢Stefan的回复。但为了最终传递额外的登录参数,我所做的是实现AuthenticationProvider并扩展AbstractAuthenticationProcessingFilter和UsernamePasswordAuthenticationToken。至于记忆我功能,我扩展了PersistentTokenBasedMemberMeservices和PersistentMemberMetoken,并实现了PersistentTokenRepository。