本文将带您了解关于SpringSecurity打开弹出窗口登录的新内容,同时我们还将为您解释开启springsecurity的相关知识,另外,我们还将为您提供关于springboot整合springs
本文将带您了解关于Spring Security打开弹出窗口登录的新内容,同时我们还将为您解释开启spring security的相关知识,另外,我们还将为您提供关于spring boot 整合spring security中spring security版本升级的遇到的坑、spring security 4 多登录入口配置(spring-security-multiple-entry-points)、Spring Security 4自定义登录j_spring_security_check返回http 302、Spring security 5.0:spring security savedrequest 为空的实用信息。
本文目录一览:- Spring Security打开弹出窗口登录(开启spring security)
- spring boot 整合spring security中spring security版本升级的遇到的坑
- spring security 4 多登录入口配置(spring-security-multiple-entry-points)
- Spring Security 4自定义登录j_spring_security_check返回http 302
- Spring security 5.0:spring security savedrequest 为空
Spring Security打开弹出窗口登录(开启spring security)
有人知道当用户执行需要进行身份验证的操作而不需要进行身份验证时,如何打开弹出式登录名进行身份验证(使用Spring Security)。
例如:假设该页面有一个“立即购买”按钮,该按钮将产品添加到购物车并执行结帐(“立即购买”页面)(如果用户已经通过身份验证),或者打开一个弹出窗口供用户执行身份验证。
如果身份验证成功,那么spring会重定向到“立即购买”页面,或者停留在打开弹出窗口的页面(错误消息为“ wrong login”)。
我已经在Google中搜索了一种解决方案,但是没有运气。
有人可以指出我正确的方向吗?
谢谢
答案1
小编典典只是一个想法,还没有时间进行测试。仅在客户端。
- 在链接/按钮单击事件上放置事件监听器
- 使用Javascript并通过以下方式调用表单操作或链接
XMLHttpRequest
- 检查HTTP状态代码:
xhr.status
- 如果(OK)替换的目标URL(当前的URL 使用HTML5的历史API),并与替换整个文件
xhr.responseText
(WHAT FOR通过W3C DOM更换整个HTML文档的其他选项 - 否则,如果(重定向)只是遵循重定向
- 否则,如果(未经授权)打开弹出窗口
spring boot 整合spring security中spring security版本升级的遇到的坑
在spring security3.x的版本中
hasAnyRole这个方法不会对我们需要认证的身份前面加个前缀ROLE_,在3.x版本hasRole的源码如下
public final boolean hasAnyRole(String... roles) {
Set<String> roleSet = getAuthoritySet();
for (String role : roles) {
if (roleSet.contains(role)) {
return true;
}
}
return false;
}
而4.x版本下的会根据我的具体情况看看是不是要加前缀,代码如下
public final boolean hasAnyRole(String... roles) {
return hasAnyAuthorityName(defaultRolePrefix, roles);
}
private boolean hasAnyAuthorityName(String prefix, String... roles) {
Set<String> roleSet = getAuthoritySet();
for (String role : roles) {
String defaultedRole = getRoleWithDefaultPrefix(prefix, role);
if (roleSet.contains(defaultedRole)) {
return true;
}
}
return false;
}
private static String getRoleWithDefaultPrefix(String defaultRolePrefix, String role) {
if (role == null) {
return role;
}
if (defaultRolePrefix == null || defaultRolePrefix.length() == 0) {
return role;
}
if (role.startsWith(defaultRolePrefix)) {
return role;
}
return defaultRolePrefix + role;
}
这里的这个坑要小心,如果加了Role_前缀,那么你登录时的角色的前面也需要加Role_才行,不然会认证失败,然后就是403页面了。(ps:hasRole这个方法也有这个版本问题,具体也是和hasAnyRole差不多。)
spring security 4 多登录入口配置(spring-security-multiple-entry-points)
详见转贴文章
Spring Security 4自定义登录j_spring_security_check返回http 302
如何解决Spring Security 4自定义登录j_spring_security_check返回http 302?
在Spring Security 4.x中,登录URL已更改为,login
而不是 j_spring_security_check
,请参阅从Spring Security 3.x迁移至4.x(XML配置)。
<form name=''f''action="login" method=''POST''>
<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}" />
<table>
<tbody>
<tr>
<td>User Name</td>
<td><input type="text" name="username" size="30" /></td>
</tr>
<tr>
<td>Password</td>
<td><input type="password" name="password" size="30" /></td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="login" /></td>
</tr>
</tbody>
</table>
</form>
解决方法
我在这里问了有关最新的Spring框架和基于代码的配置的问题
initializer
public class AppInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { SecurityConfig.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] { MvcConfig.class };
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
MVC config
@EnableWebMvc
@ComponentScan({ "com.appname.controller" })
public class MvcConfig extends WebMvcConfigurerAdapter {
@Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/jsp/");
resolver.setSuffix(".jsp");
return resolver;
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/res/**").addResourceLocations("/res/");
}
}
security config
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true,jsr250Enabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private CustomUserDetailsService customUserDetailsService;
public SecurityConfig() {
customUserDetailsService = new CustomUserDetailsService();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception {
auth.inMemoryAuthentication().withUser("user").password("password")
.roles("USER");
auth.userDetailsService(customUserDetailsService);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/res/**").permitAll()
.and().authorizeRequests()
.anyRequest().hasRole("USER")
.and().formLogin().loginPage("/account/signin").permitAll()
.and().logout().permitAll();
}
}
security initializer
public class SecurityInitializer extends
AbstractSecurityWebApplicationInitializer {
}
custom login
public class CustomUserDetailsService implements UserDetailsService {
private AccountRepository accountRepository;
public CustomUserDetailsService() {
this.accountRepository = new AccountRepository();
}
@Override
public UserDetails loadUserByUsername(String email)
throws UsernameNotFoundException {
Account account = accountRepository.getAccountByEmail(email);
if (account == null) {
throw new UsernameNotFoundException("Invalid email/password.");
}
Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
authorities.add(new SimpleGrantedAuthority("USER"));
return new User(account.getEmail(),account.getPassword(),authorities);
}
}
但是,现在我有关于自定义登录的新问题。
发布到j_spring_security_check时,我会收到http 302。
我正在请求/,但登录后仍保留在登录页面上。
因为我使用的是Spring Security 4.x版本,并且纯粹基于代码的配置,所以在Internet上找不到更多参考。任何人都可以帮助找出原因。
EDIT
org.springframework.beans.factory.BeanCreationException:
Error creating bean with name ''securityConfig'':
Injection of autowired dependencies failed;
nested exception is org.springframework.beans.factory.BeanCreationException:
Could not autowire field:
private org.springframework.security.core.userdetails.UserDetailsService sg.mathschool.infra.SecurityConfig.userDetailsService;
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type [org.springframework.security.core.userdetails.UserDetailsService] found for dependency:
expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations:
{@org.springframework.beans.factory.annotation.Autowired(required=true),@org.springframework.beans.factory.annotation.Qualifier(value=userDetailsService)}
I changed CustomUserDetailsService
@Service("userDetailsService")
public class CustomUserDetailsService implements UserDetailsService {
private AccountRepository accountRepository;
public CustomUserDetailsService() {
this.accountRepository = new AccountRepository();
}
@Override
@Transactional(readOnly = true)
public UserDetails loadUserByUsername(String email)
throws UsernameNotFoundException {
Account account = accountRepository.getAccountByEmail(email);
if (account == null) {
throw new UsernameNotFoundException("Invalid email/password.");
}
Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
authorities.add(new SimpleGrantedAuthority("USER"));
return new User(account.getEmail(),authorities);
}
}
和 security config
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true,jsr250Enabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
@Qualifier("userDetailsService")
private UserDetailsService userDetailsService;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth)
throws Exception {
auth.inMemoryAuthentication().withUser("user").password("password")
.roles("USER");
auth.userDetailsService(userDetailsService).passwordEncoder(
passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/res/**").permitAll()
.antMatchers("/account/**").permitAll().anyRequest()
.hasRole("USER").and().formLogin().loginPage("/account/signin")
.failureUrl("/account/signin?error").usernameParameter("email")
.passwordParameter("password").and().logout()
.logoutSuccessUrl("/account/signin?logout").and().csrf();
}
@Bean
public PasswordEncoder passwordEncoder() {
PasswordEncoder encoder = new BCryptPasswordEncoder();
return encoder;
}
}
Spring security 5.0:spring security savedrequest 为空
如何解决Spring security 5.0:spring security savedrequest 为空?
我有一个 spring boot 客户端应用程序,我在其中使用 spring-boot-starter-oauth2-client 和 spring-boot-starter-security。同一个应用程序在一个环境中运行良好,但是在另一个环境中部署后,我可以看到 spring security 保存的请求为空,这就是它不断重定向到登录页面的原因。
启用 spring 安全调试日志后,我可以看到身份验证成功并检索到用户详细信息。但是,它继续重定向到“/”,因为spring security 保存的请求为空。
我不知道问题出在哪里,为什么它能够在一种环境中而不是在另一种环境中保存请求。我应该从哪里开始寻找?任何帮助将不胜感激。
应用程序未重定向的调试日志
{"timestamp":"2021-05-12T17:24:40.918+10:00","app":"my-protected-application","logLevel":"INFO","thread":"http-nio-8080-exec-1","eventSource":"org.apache.catalina.core.ContainerBase.[Tomcat].[localhost].[/]","message":"Initializing Spring dispatcherServlet ''dispatcherServlet''"}
{"timestamp":"2021-05-12T17:24:41.104+10:00","traceId":"2efe5d4e6d04f787","spanId":"2efe5d4e6d04f787","logLevel":"DEBUG","eventSource":"org.springframework.security.web.util.matcher.AntPathRequestMatcher","message":"Checking match of request : ''/actuator/health/readiness''; against ''/actuator/info''"}
{"timestamp":"2021-05-12T17:24:41.112+10:00","message":"Checking match of request : ''/actuator/health/readiness''; against ''/actuator/health/readiness''"}
{"timestamp":"2021-05-12T17:24:41.112+10:00","eventSource":"org.springframework.security.web.FilterChainProxy","message":"/actuator/health/readiness has an empty filter list"}
{"timestamp":"2021-05-12T17:24:55.666+10:00","traceId":"9681ad4d267d4beb","spanId":"9681ad4d267d4beb","thread":"http-nio-8080-exec-2","message":"Checking match of request : ''/oauth2/authorization/my-protected-application''; against ''/actuator/info''"}
{"timestamp":"2021-05-12T17:24:55.666+10:00","message":"Checking match of request : ''/oauth2/authorization/my-protected-application''; against ''/actuator/health/readiness''"}
{"timestamp":"2021-05-12T17:24:55.666+10:00","message":"Checking match of request : ''/oauth2/authorization/my-protected-application''; against ''/actuator/health/liveness''"}
{"timestamp":"2021-05-12T17:24:55.668+10:00","message":"/oauth2/authorization/my-protected-application at position 1 of 14 in additional filter chain; firing Filter: ''WebAsyncManagerIntegrationFilter''"}
{"timestamp":"2021-05-12T17:24:55.670+10:00","message":"/oauth2/authorization/my-protected-application at position 2 of 14 in additional filter chain; firing Filter: ''SecurityContextPersistenceFilter''"}
{"timestamp":"2021-05-12T17:24:55.670+10:00","eventSource":"org.springframework.security.web.context.HttpSessionSecurityContextRepository","message":"No HttpSession currently exists"}
{"timestamp":"2021-05-12T17:24:55.670+10:00","message":"No SecurityContext was available from the HttpSession: null. A new one will be created."}
{"timestamp":"2021-05-12T17:24:55.673+10:00","message":"/oauth2/authorization/my-protected-application at position 3 of 14 in additional filter chain; firing Filter: ''HeaderWriterFilter''"}
{"timestamp":"2021-05-12T17:24:55.674+10:00","message":"/oauth2/authorization/my-protected-application at position 4 of 14 in additional filter chain; firing Filter: ''logoutFilter''"}
{"timestamp":"2021-05-12T17:24:55.674+10:00","eventSource":"org.springframework.security.web.util.matcher.OrRequestMatcher","message":"Trying to match using Ant [pattern=''/logout'',GET]"}
{"timestamp":"2021-05-12T17:24:55.675+10:00","message":"Checking match of request : ''/oauth2/authorization/my-protected-application''; against ''/logout''"}
{"timestamp":"2021-05-12T17:24:55.675+10:00",POST]"}
{"timestamp":"2021-05-12T17:24:55.675+10:00","message":"Request ''GET /oauth2/authorization/my-protected-application'' doesn''t match ''POST /logout''"}
{"timestamp":"2021-05-12T17:24:55.675+10:00",PUT]"}
{"timestamp":"2021-05-12T17:24:55.675+10:00","message":"Request ''GET /oauth2/authorization/my-protected-application'' doesn''t match ''PUT /logout''"}
{"timestamp":"2021-05-12T17:24:55.675+10:00",DELETE]"}
{"timestamp":"2021-05-12T17:24:55.675+10:00","message":"Request ''GET /oauth2/authorization/my-protected-application'' doesn''t match ''DELETE /logout''"}
{"timestamp":"2021-05-12T17:24:55.675+10:00","message":"No matches found"}
{"timestamp":"2021-05-12T17:24:55.676+10:00","message":"/oauth2/authorization/my-protected-application at position 5 of 14 in additional filter chain; firing Filter: ''OAuth2AuthorizationRequestRedirectFilter''"}
{"timestamp":"2021-05-12T17:24:55.676+10:00","message":"Checking match of request : ''/oauth2/authorization/my-protected-application''; against ''/oauth2/authorization/{registrationId}''"}
{"timestamp":"2021-05-12T17:24:55.676+10:00","message":"Checking match of request : ''/oauth2/authorization/my-protected-application''; against ''/oauth2/authorization/{registrationId}''"}
解决方法
您是直接调用登录 URL 而不是尝试通过登录页面登录吗?
用户请求的请求数据存储在 requestCache
中。
此处存储的请求数据为 savedRequest
。
Spring security
在用户身份验证后重定向 requestCache
和 savedRequest
对象。
SavedRequest
必须为空,因为如果不使用登录页面直接使用 URL,则前一个请求中没有请求数据。
您可以尝试从登录页面登录或使用 Referrer
标头获取页面 URL。
我们今天的关于Spring Security打开弹出窗口登录和开启spring security的分享已经告一段落,感谢您的关注,如果您想了解更多关于spring boot 整合spring security中spring security版本升级的遇到的坑、spring security 4 多登录入口配置(spring-security-multiple-entry-points)、Spring Security 4自定义登录j_spring_security_check返回http 302、Spring security 5.0:spring security savedrequest 为空的相关信息,请在本站查询。
本文标签: