spring 安全:进行 mysql 身份验证
spring security : make a mysql authentication
我有 Spring 安全方面的问题。
我正在尝试通过 mysql 数据检查进行身份验证。
我正在使用 AngularJs、Spring 启动和 Spring 安全。
我有一个由 $http.post(...) 调用的网络服务 rest。
当我启动我的应用程序时,如果我使用 chrome 插件 "Advanced Rest Client" > “http://localhost:8080/check-login” 测试我的网络服务;它有效,我收到代码 200:OK.
但是如果我想通过 Chrome 使用相同的 URL 访问我的网络服务。 A window 开启认证。我认为这是 Spring 安全部门的预认证。但我不知道如何禁用它。
这是一个问题,因为当我想用我的浏览器访问网络服务时,它说:“http://localhost:8080/check-login 401 unauthaurized”
编辑:这是我的代码:
HTML :
<form role="form" ng-submit="controller.login()">
<div class="form-group">
<label for="username">Username:</label>
<input type="text" class="form-control" id="username" name="username" ng-model="controller.credentials.username"/>
</div>
<div class="form-group">
<label for="password">Password:</label>
<input type="password" class="form-control" id="password" name="password" ng-model="controller.credentials.password"/>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
JS :
myModule.controller('NavCtrl',function($rootScope, $location, $http){
var self = this
var authenticate = function(credentials, callback) {
var headers = credentials ? {authorization : "Basic " + btoa(credentials.username + ":" + credentials.password)} : {};
$http.get('user', {headers : headers}).then(
function(response) {
if (response.data.name) {
$rootScope.authenticated = true;
} else {
$rootScope.authenticated = false;
}
callback && callback();
},
function() {
$rootScope.authenticated = false;
callback && callback();
}
);
}
authenticate();
self.credentials = {};
self.login = function() {
authenticate(self.credentials, function() {
if ($rootScope.authenticated) {
$location.path("/");
self.error = false;
} else {
$location.path("/login");
self.error = true;
}
});
};
});
我的 Java 休息:
@RestController
public class TestRest {
@RequestMapping("/user")
public Principal user(Principal user){
return user;
}
}
我的 Java Spring 引导和安全配置:
@SpringBootApplication
public class BusinessBootApplication {
public static void main(String[] args) {
SpringApplication.run(BusinessBootApplication.class, args);
}
@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
protected static class SecurityConfiguration extends WebSecurityConfigurerAdapter{
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic()
.and()
.authorizeRequests()
.antMatchers("/index.html","/home.html","/login.html","/").permitAll()
.anyRequest()
.authenticated()
.and()
.addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class)
.csrf()
.csrfTokenRepository(csrfTokenRepository());
}
private CsrfTokenRepository csrfTokenRepository() {
HttpSessionCsrfTokenRepository repo = new HttpSessionCsrfTokenRepository();
repo.setHeaderName("X-XSRF-TOKEN");
return repo;
}
}
}
最后,我的 Java 关于 UserDetailsService
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
public UserDao userDao;
@Autowired
public UserDetailsServiceImpl(UserDao _userDao) {
super();
userDao = _userDao;
}
@Override
public UserDetails loadUserByUsername(String arg0) throws UsernameNotFoundException {
UserDetailsImpl userDetailsImpl = null;
User user = userDao.findByLogin(arg0);
if(user == null){
throw new UsernameNotFoundException("Login not found");
} else{
userDetailsImpl = new UserDetailsImpl(user);
}
return userDetailsImpl;
}
}
public class UserDetailsImpl implements UserDetails {
/** The Constant serialVersionUID. */
private static final long serialVersionUID = 1L;
/** The _username. */
private String username;
/** The _password. */
private String password;
public UserDetailsImpl(User user) {
username = user.getLogin();
password = user.getPwd();
}
/**
* @param password the password to set
*/
public void setPassword(String password) {
this.password = password;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
// TODO Auto-generated method stub
return null;
}
@Override
public String getPassword() {
// TODO Auto-generated method stub
return null;
}
/**
* @param username the username to set
*/
public void setUsername(String username) {
this.username = username;
}
@Override
public String getUsername() {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean isAccountNonExpired() {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean isAccountNonLocked() {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean isCredentialsNonExpired() {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean isEnabled() {
// TODO Auto-generated method stub
return false;
}
}
你有想法吗?谢谢
Chrome 从与 Internet Explorer 相同的 Internet 选项中获取其受信任的站点设置。您可以从 Chrome 此处访问该对话框:
属性 -> 显示高级设置 -> 更改代理设置 -> 安全 -> 受信任的站点
请注意:您将在第一次访问受信任的站点时被要求登录。
/check-login 是你的登录页面?如果是-
这个 url 也应该放在 antmatcher("/check-login").permitAll().
/check-login
"check-login" url用于登录。如果不放在permitAll里面,/check-login page也需要认证。这将禁用 Spring 安全性的身份验证。
此 window 是基本身份验证 window,在您的代码中您使用的是基本身份验证 (httpBasic) :
http.httpBasic()
.and()
.authorizeRequests()
.antMatchers("/index.html","/home.html","/login.html","/").permitAll()
.anyRequest()
.authenticated()
因此,如果您尝试访问受保护的 URL,请将 spring 安全配置为应用基本身份验证。
基于此配置,Chrome 正在检查 http 请求是否包含身份验证 Header(其中包括用户凭据),如果是,则身份验证 window 未打开,否则 chrome 将打开身份验证 window 以插入用户名和密码。
要解决 window 问题,您需要在 angularJS 代码中处理基本身份验证,就像您在下面的代码中所写的那样(请通过监视请求来检查此代码是否正常工作 header 在 chrome 开发者工具中)
var headers = credentials ? {authorization : "Basic " + btoa(credentials.username + ":" + credentials.password)} : {};
$http.get('user', {headers : headers}).then(
function(response) {
if (response.data.name) {
$rootScope.authenticated = true;
} else {
$rootScope.authenticated = false;
}
callback && callback();
},
function() {
$rootScope.authenticated = false;
callback && callback();
}
);
请注意:
使用Advanced Rest Client Tool时,可以通过Basic认证header,如果不通过header,认证window将无法开启[=12] =]
我有 Spring 安全方面的问题。
我正在尝试通过 mysql 数据检查进行身份验证。 我正在使用 AngularJs、Spring 启动和 Spring 安全。
我有一个由 $http.post(...) 调用的网络服务 rest。 当我启动我的应用程序时,如果我使用 chrome 插件 "Advanced Rest Client" > “http://localhost:8080/check-login” 测试我的网络服务;它有效,我收到代码 200:OK.
但是如果我想通过 Chrome 使用相同的 URL 访问我的网络服务。 A window 开启认证。我认为这是 Spring 安全部门的预认证。但我不知道如何禁用它。
这是一个问题,因为当我想用我的浏览器访问网络服务时,它说:“http://localhost:8080/check-login 401 unauthaurized”
编辑:这是我的代码:
HTML :
<form role="form" ng-submit="controller.login()">
<div class="form-group">
<label for="username">Username:</label>
<input type="text" class="form-control" id="username" name="username" ng-model="controller.credentials.username"/>
</div>
<div class="form-group">
<label for="password">Password:</label>
<input type="password" class="form-control" id="password" name="password" ng-model="controller.credentials.password"/>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
JS :
myModule.controller('NavCtrl',function($rootScope, $location, $http){
var self = this
var authenticate = function(credentials, callback) {
var headers = credentials ? {authorization : "Basic " + btoa(credentials.username + ":" + credentials.password)} : {};
$http.get('user', {headers : headers}).then(
function(response) {
if (response.data.name) {
$rootScope.authenticated = true;
} else {
$rootScope.authenticated = false;
}
callback && callback();
},
function() {
$rootScope.authenticated = false;
callback && callback();
}
);
}
authenticate();
self.credentials = {};
self.login = function() {
authenticate(self.credentials, function() {
if ($rootScope.authenticated) {
$location.path("/");
self.error = false;
} else {
$location.path("/login");
self.error = true;
}
});
};
});
我的 Java 休息:
@RestController
public class TestRest {
@RequestMapping("/user")
public Principal user(Principal user){
return user;
}
}
我的 Java Spring 引导和安全配置:
@SpringBootApplication
public class BusinessBootApplication {
public static void main(String[] args) {
SpringApplication.run(BusinessBootApplication.class, args);
}
@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
protected static class SecurityConfiguration extends WebSecurityConfigurerAdapter{
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic()
.and()
.authorizeRequests()
.antMatchers("/index.html","/home.html","/login.html","/").permitAll()
.anyRequest()
.authenticated()
.and()
.addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class)
.csrf()
.csrfTokenRepository(csrfTokenRepository());
}
private CsrfTokenRepository csrfTokenRepository() {
HttpSessionCsrfTokenRepository repo = new HttpSessionCsrfTokenRepository();
repo.setHeaderName("X-XSRF-TOKEN");
return repo;
}
}
}
最后,我的 Java 关于 UserDetailsService
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
public UserDao userDao;
@Autowired
public UserDetailsServiceImpl(UserDao _userDao) {
super();
userDao = _userDao;
}
@Override
public UserDetails loadUserByUsername(String arg0) throws UsernameNotFoundException {
UserDetailsImpl userDetailsImpl = null;
User user = userDao.findByLogin(arg0);
if(user == null){
throw new UsernameNotFoundException("Login not found");
} else{
userDetailsImpl = new UserDetailsImpl(user);
}
return userDetailsImpl;
}
}
public class UserDetailsImpl implements UserDetails {
/** The Constant serialVersionUID. */
private static final long serialVersionUID = 1L;
/** The _username. */
private String username;
/** The _password. */
private String password;
public UserDetailsImpl(User user) {
username = user.getLogin();
password = user.getPwd();
}
/**
* @param password the password to set
*/
public void setPassword(String password) {
this.password = password;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
// TODO Auto-generated method stub
return null;
}
@Override
public String getPassword() {
// TODO Auto-generated method stub
return null;
}
/**
* @param username the username to set
*/
public void setUsername(String username) {
this.username = username;
}
@Override
public String getUsername() {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean isAccountNonExpired() {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean isAccountNonLocked() {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean isCredentialsNonExpired() {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean isEnabled() {
// TODO Auto-generated method stub
return false;
}
}
你有想法吗?谢谢
Chrome 从与 Internet Explorer 相同的 Internet 选项中获取其受信任的站点设置。您可以从 Chrome 此处访问该对话框:
属性 -> 显示高级设置 -> 更改代理设置 -> 安全 -> 受信任的站点
请注意:您将在第一次访问受信任的站点时被要求登录。
/check-login 是你的登录页面?如果是-
这个 url 也应该放在 antmatcher("/check-login").permitAll().
/check-login
"check-login" url用于登录。如果不放在permitAll里面,/check-login page也需要认证。这将禁用 Spring 安全性的身份验证。
此 window 是基本身份验证 window,在您的代码中您使用的是基本身份验证 (httpBasic) :
http.httpBasic()
.and()
.authorizeRequests()
.antMatchers("/index.html","/home.html","/login.html","/").permitAll()
.anyRequest()
.authenticated()
因此,如果您尝试访问受保护的 URL,请将 spring 安全配置为应用基本身份验证。
基于此配置,Chrome 正在检查 http 请求是否包含身份验证 Header(其中包括用户凭据),如果是,则身份验证 window 未打开,否则 chrome 将打开身份验证 window 以插入用户名和密码。
要解决 window 问题,您需要在 angularJS 代码中处理基本身份验证,就像您在下面的代码中所写的那样(请通过监视请求来检查此代码是否正常工作 header 在 chrome 开发者工具中)
var headers = credentials ? {authorization : "Basic " + btoa(credentials.username + ":" + credentials.password)} : {};
$http.get('user', {headers : headers}).then(
function(response) {
if (response.data.name) {
$rootScope.authenticated = true;
} else {
$rootScope.authenticated = false;
}
callback && callback();
},
function() {
$rootScope.authenticated = false;
callback && callback();
}
);
请注意: 使用Advanced Rest Client Tool时,可以通过Basic认证header,如果不通过header,认证window将无法开启[=12] =]