14

我在 Spring 中创建身份验证服务。

我正在使用 UserDetailsS​​ervice 来获取表单变量,但我发现 loadUserByUsername 只有一个变量 - userName。

如何获取密码?

public class userAuthentication implements UserDetailsService{

    private @Autowired
    ASPWebServicesUtils aspWebServicesUtils;

    @Override
    public UserDetails loadUserByUsername(String name) throws UsernameNotFoundException {

        //how to get password ?

        User user = new User("test", "test", true, true, true, true, getAuthorities(true));

        return user;  

    }

    private List<GrantedAuthority> getAuthorities(boolean isAdmin){

        List<GrantedAuthority> authorityList = new ArrayList<GrantedAuthority>(2);
        authorityList.add(new SimpleGrantedAuthority("USER_ROLE"));
        if(isAdmin){
            authorityList.add(new SimpleGrantedAuthority("ADMIN_ROLE"));
        }
        return authorityList;

    }
//...
}

谢谢

4

6 回答 6

20

如果查看User对象,构造函数中的第二个参数是密码。

UserDetailsS​​ervice用于从后端结构(如数据库)加载用户。当用户尝试使用用户名和密码登录时调用loadUserByUsername方法,然后由服务负责加载用户定义并将其返回给安全框架。所需的详细信息包括usernamepasswordaccountNonExpiredcredentialsNonExpiredaccountNonLocked等数据authorities

一旦 spring security 接收到用户对象,它将根据用户输入的密码和其他数据(如用户帐户状态(accountNonExpired、credentialsNonExpired 等))验证用户

于 2013-02-18T14:56:18.543 回答
17

检索用户信息和提供身份验证信息的一些标准(开箱即用)机制包括:

  • inMemoryAuthentication
  • jdbc身份验证
  • ldap身份验证
  • 用户详情服务

如果上述不适合您的目的并且您需要自定义解决方案,则可以创建和配置新的身份验证提供程序,如下所示:

安全配置:

@Configuration
@EnableWebMvcSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    @Autowired
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(new CustomAuthenticationProvider());
    }

    ....
}

身份验证提供者:

public class CustomAuthenticationProvider implements AuthenticationProvider {

    @Override
    public Authentication authenticate(Authentication authentication)
            throws AuthenticationException {
        String name = authentication.getName();
        // You can get the password here
        String password = authentication.getCredentials().toString();

        // Your custom authentication logic here
        if (name.equals("admin") && password.equals("pwd")) {
            Authentication auth = new UsernamePasswordAuthenticationToken(name,
                    password);

            return auth;
        }

        return null;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }

}
于 2015-09-28T20:03:21.257 回答
3

我相信 aUserDetailsService应该用于UserDetails从一些后端存储、数据库、平面文件等获取对象。一旦你有了它UserDetails,spring security(或你)必须将它与用户名(或其他主体)和密码进行比较(凭据)由用户提供以验证该用户。

我认为您没有按照预期的方式使用它。

于 2013-02-18T14:50:32.433 回答
3

UserDetailsService通过以下方式获取密码request.getParameter("password")

public class MyUserDetailsService implements UserDetailsService {

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String password = request.getParameter("password"); // get from request parameter
        ......
    }
}

RequestContextHolder是基于ThreadLocal.

如果您的项目基于 Spring Framework(不是 Spring Boot),请添加RequestContextListener到 web.xml

<listener>
    <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
于 2018-11-22T01:46:55.313 回答
1

XML 实现:

<authentication-manager  alias="loginAuthenticationManager">
    <authentication-provider ref="loginAuthenticationProvider" />
</authentication-manager>

<!-- Bean implementing AuthenticationProvider of Spring Security -->
<beans:bean id="loginAuthenticationProvider" class="com.config.LoginAuthenticationProvider">
</beans:bean>

身份验证提供者:

public class LoginAuthenticationProvider implements AuthenticationProvider {
    @Override
    public Authentication authenticate(Authentication authentication)
            throws AuthenticationException {
        String name = authentication.getName();
        // You can get the password here
        String password = authentication.getCredentials().toString();

        // Your custom authentication logic here
        if (name.equals("admin") && password.equals("pwd")) {
            List<GrantedAuthority> grantedAuths = new ArrayList<>();
            grantedAuths.add(new SimpleGrantedAuthority("ROLE_USER"));
            return new UsernamePasswordAuthenticationToken(name, password, grantedAuths);
        }
        return null;
    }
    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }
}
于 2016-08-10T11:07:09.203 回答
0

loadUserByUsername(String name)是在您的服务实现的接口(我认为是 userServicedetails)上定义的方法。您必须编写实现。

就像你必须为 getPassword() 或类似的东西编写实现一样...... spring 不提供。我想密码存储在您的用户对象中,但您写道……您创建了一个getPassword()方法吗?

于 2013-02-18T14:46:14.450 回答