gpt4 book ai didi

java - 用户名和密码未与 Spring 中的身份验证映射

转载 作者:太空宇宙 更新时间:2023-11-04 12:17:07 24 4
gpt4 key购买 nike

我正在使用 Spring 4.3.1.RELEASE 版本,它是自定义身份验证登录应用程序。但我遇到了问题

首先看一下代码

CustomAuthenticationProvider.java

@Component
@Qualifier(value = "customAuthenticationProvider")
public class CustomAuthenticationProvider implements AuthenticationProvider{


public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = authentication.getName();
String password = (String) authentication.getCredentials();
User user = new User();
user.setUsername(username);
user.setPassword(password);


Role r = new Role();
r.setName("ROLE_ADMIN");
List<Role> roles = new ArrayList<Role>();
roles.add(r);


Collection<? extends GrantedAuthority> authorities = roles;
return new UsernamePasswordAuthenticationToken(user, password, authorities);
}

public boolean supports(Class<?> arg0) {
return true;
}

}

SecurityConfiguration.java

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

@Autowired
private CustomAuthenticationProvider customAuthenticationProvider;

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(customAuthenticationProvider);
}

//.csrf() is optional, enabled by default, if using WebSecurityConfigurerAdapter constructor
@Override
protected void configure(HttpSecurity http) throws Exception {

http.authorizeRequests()
.antMatchers("/admin/**").access("hasRole('ROLE_USER')")
.and()
.formLogin()
.loginPage("/login").failureUrl("/login?error")
.usernameParameter("username").passwordParameter("password")
.and()
.logout().logoutSuccessUrl("/login?logout")
.and()
.csrf();
}
}

登录.jsp这是我的登录页面

  <form name="loginForm" novalidate ng-submit="ctrl.login(user)">
<div class="form-group" ng-class="{'has-error': loginForm.username.$invalid}">
<input class="form-control" name="username" id="username" type="text"
placeholder="Username" required ng-model="user.username" />
<span class="help-block"
ng-show="loginForm.username.$error.required">Required</span>
</div>
<div class="form-group" ng-class="{'has-error': loginForm.password.$invalid}">
<input class="form-control" name="password" id="password" type="password"
placeholder="Password" required ng-model="user.password" />
<span class="help-block"
ng-show="loginForm.password.$error.required">Required</span>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary pull-right"
value="Login" title="Login" ng-disabled="!loginForm.$valid">
<span>Login</span>
</button>
</div>
</form>

关于 CustomAuhtenticationProvider 类中的authenticate()

  1. authentication.getCredentials();
  2. authentication.getName();

都给出空字符串,但我需要用户名和密码。

Here is IntellijIdea Debug screen shot

这是我的 AngularJS 服务

Service.js

  function loginUser(user) {
var config = {
headers: {
'csrf_token': csrfToken
}
}


var deferred = $q.defer();
$http.post("/login", user,config)
.then(
function (response) {
deferred.resolve(response.data);
},
function(errResponse){
console.error('Error while creating User');
deferred.reject(errResponse);
}
);
return deferred.promise;
}

最佳答案

您正在以 JSON 形式发送身份验证凭据,并且正在使用默认值 UsernamePasswordAuthenticationFilter尝试从 HttpServletRequest 参数中检索身份验证凭据。

它们将永远为空。您必须构建自己的自定义过滤器,该过滤器从请求正文中收到的 json 而不是 http 参数中获取身份验证凭据。

看看this

编辑:事实是,您没有获得从 Angular Controller 发送的登录凭据。原因可能是,如果您在请求正文中将它们作为 json 发送,则不能依赖默认的 UsernamePasswordAuthenticationFilter,因为它会尝试构建读取 HttpServletRequest 参数的 Authentication 对象。

公共(public)类 UsernamePasswordAuthenticationFilter 扩展 抽象身份验证处理过滤器{

public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse response) throws AuthenticationException {
if (postOnly && !request.getMethod().equals("POST")) {
throw new AuthenticationServiceException(
"Authentication method not supported: " + request.getMethod());
}

String username = obtainUsername(request);
String password = obtainPassword(request);
...
}

/**
* Enables subclasses to override the composition of the password, such as by
* including additional values and a separator.
* <p>
* This might be used for example if a postcode/zipcode was required in addition to
* the password. A delimiter such as a pipe (|) should be used to separate the
* password and extended value(s). The <code>AuthenticationDao</code> will need to
* generate the expected password in a corresponding manner.
* </p>
*
* @param request so that request attributes can be retrieved
*
* @return the password that will be presented in the <code>Authentication</code>
* request token to the <code>AuthenticationManager</code>
*/
protected String obtainPassword(HttpServletRequest request) {
return request.getParameter(passwordParameter);
}

/**
* Enables subclasses to override the composition of the username, such as by
* including additional values and a separator.
*
* @param request so that request attributes can be retrieved
*
* @return the username that will be presented in the <code>Authentication</code>
* request token to the <code>AuthenticationManager</code>
*/
protected String obtainUsername(HttpServletRequest request) {
return request.getParameter(usernameParameter);
}

您应该扩展此过滤器,重写 attemptsAuthentication() 方法,以避免在恢复此凭据时调用获取用户名和获取密码。相反,编写一个自定义方法,您将在其中读取 ServletRequest's InputStream并使用您以前使用的 json 库解析为对象。我一般用jackson this way

关于java - 用户名和密码未与 Spring 中的身份验证映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39268994/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com