Spring security Spring Security';s@PreAuthorize导致415“;“不支持的媒体类型”;错误
我在应用程序中通过Java配置使用Spring引导、Spring数据JPA、Spring数据REST和Spring安全性。我正在尝试将这个@PreAuthorize注释添加到我的UserPrefsRESTController中的以下方法中 界面:Spring security Spring Security';s@PreAuthorize导致415“;“不支持的媒体类型”;错误,spring-security,Spring Security,我在应用程序中通过Java配置使用Spring引导、Spring数据JPA、Spring数据REST和Spring安全性。我正在尝试将这个@PreAuthorize注释添加到我的UserPrefsRESTController中的以下方法中 界面: package com.company.services.rest; import com.company.server.model.user.preferences.UserPrefs; import com.company.server.user
package com.company.services.rest;
import com.company.server.model.user.preferences.UserPrefs;
import com.company.server.user.prefs.UserPrefsDTO;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
@RequestMapping("/api/userprefs")
public interface UserPrefsRESTController {
@RequestMapping(method = RequestMethod.POST, produces = "application/json")
@PreAuthorize("#userPrefs.id == principal.username or hasRole('ADMIN')")
ResponseEntity<UserPrefsDTO> setUserPrefs(@RequestBody UserPrefs userPrefs);
@RequestMapping(method = RequestMethod.GET, produces = "application/json")
ResponseEntity<UserPrefsDTO> getUserPrefs(@RequestParam String id);
}
package com.company.services.rest;
import com.company.server.model.user.preferences.UserPrefs;
import com.company.server.user.prefs.UserPrefsDTO;
import com.company.server.user.prefs.UserPrefsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserPrefsRESTControllerImpl implements UserPrefsRESTController {
@Autowired
private UserPrefsService userPrefsService;
@Override
public ResponseEntity<UserPrefsDTO> setUserPrefs(UserPrefs userPrefs) {
UserPrefsDTO response;
try {
response = userPrefsService.setUserPrefsValue(userPrefs);
} catch (final IllegalArgumentException e) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);
}
return ResponseEntity.ok(response);
}
@Override
public ResponseEntity<UserPrefsDTO> getUserPrefs(String id) {
return ResponseEntity.ok(userPrefsService.getUserPrefs(id));
}
}
package com.company.server.user.prefs;
import java.io.Serializable;
public class UserPrefsDTO implements Serializable{
private String id;
private String value;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
package com.company.spring.boot;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("password").roles("USER").and()
.withUser("runuser").password("password").roles("USER", "RUN").and()
.withUser("admin").password("password").roles("USER", "RUN", "ADMIN");
}
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin().permitAll().and()
.logout().permitAll().and()
.authorizeRequests()
.anyRequest().authenticated()
.and().csrf().disable()
.httpBasic();
}
}
package com.company.server.model.repositories;
import com.company.server.model.ModelConstants;
import com.company.server.model.user.preferences.UserPrefs;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.security.access.prepost.PreAuthorize;
import javax.persistence.PersistenceContext;
@PersistenceContext(name = ModelConstants.DOMAIN_ID)
@RepositoryRestResource(collectionResourceRel = "UserPrefs", path = "UserPrefs", itemResourceRel="UserPrefs")
public interface UserPrefsRepository extends JpaRepository<UserPrefs, String> {
@Override
@PreAuthorize("hasRole('ADMIN')")
Page<UserPrefs> findAll(Pageable pageable);
@PostAuthorize("returnObject != null && returnObject.id == principal.username or hasRole('ADMIN')")
UserPrefs findById(@Param("id") String id);
}
package com.company.server.model.user.preferences;
import org.springframework.data.rest.core.annotation.HandleBeforeCreate;
import org.springframework.data.rest.core.annotation.HandleBeforeDelete;
import org.springframework.data.rest.core.annotation.HandleBeforeSave;
import org.springframework.data.rest.core.annotation.RepositoryEventHandler;
import org.springframework.security.access.prepost.PreAuthorize;
@RepositoryEventHandler
@SuppressWarnings("unused")
public class UserPrefsEventHandler {
@HandleBeforeCreate
@PreAuthorize("#userPrefs.id == principal.username or hasRole('ADMIN')")
public void checkCreateAuthority(UserPrefs userPrefs) {
System.out.println("checkCreateAuthority");
}
@HandleBeforeSave
@PreAuthorize("#userPrefs.id == principal.username or hasRole('ADMIN')")
public void checkUpdateAuthority(UserPrefs userPrefs) {
System.out.println("checkUpdateAuthority");
}
@HandleBeforeDelete
@PreAuthorize("hasRole('ADMIN')")
public void checkDeleteAuthority(UserPrefs userPrefs) {
System.out.println("checkDeleteAuthority");
}
}
2017-05-11 11:51:18.784 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 1 of 13 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2017-05-11 11:51:18.786 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 2 of 13 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2017-05-11 11:51:18.787 DEBUG 10256 --- [qtp424848797-87] w.c.HttpSessionSecurityContextRepository : No HttpSession currently exists
2017-05-11 11:51:18.787 DEBUG 10256 --- [qtp424848797-87] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: null. A new one will be created.
2017-05-11 11:51:18.790 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 3 of 13 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2017-05-11 11:51:18.790 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.header.writers.HstsHeaderWriter : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@27192c6
2017-05-11 11:51:18.790 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 4 of 13 in additional filter chain; firing Filter: 'LogoutFilter'
2017-05-11 11:51:18.790 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', GET]
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'POST /api/userprefs' doesn't match 'GET /logout
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', POST]
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/userprefs'; against '/logout'
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', PUT]
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'POST /api/userprefs' doesn't match 'PUT /logout
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', DELETE]
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'POST /api/userprefs' doesn't match 'DELETE /logout
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : No matches found
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 5 of 13 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
2017-05-11 11:51:18.792 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/userprefs'; against '/login'
2017-05-11 11:51:18.792 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 6 of 13 in additional filter chain; firing Filter: 'DefaultLoginPageGeneratingFilter'
2017-05-11 11:51:18.792 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 7 of 13 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
2017-05-11 11:51:18.794 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.www.BasicAuthenticationFilter : Basic Authentication Authorization header found for user 'admin'
2017-05-11 11:51:18.795 DEBUG 10256 --- [qtp424848797-87] o.s.s.authentication.ProviderManager : Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
2017-05-11 11:51:18.802 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.www.BasicAuthenticationFilter : Authentication success: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@e0123f1f: Principal: org.springframework.security.core.userdetails.User@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_RUN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_RUN, ROLE_USER
2017-05-11 11:51:18.802 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 8 of 13 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2017-05-11 11:51:18.802 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 9 of 13 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2017-05-11 11:51:18.804 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 10 of 13 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2017-05-11 11:51:18.804 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.AnonymousAuthenticationFilter : SecurityContextHolder not populated with anonymous token, as it already contained: 'org.springframework.security.authentication.UsernamePasswordAuthenticationToken@e0123f1f: Principal: org.springframework.security.core.userdetails.User@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_RUN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_RUN, ROLE_USER'
2017-05-11 11:51:18.804 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 11 of 13 in additional filter chain; firing Filter: 'SessionManagementFilter'
2017-05-11 11:51:18.804 DEBUG 10256 --- [qtp424848797-87] s.CompositeSessionAuthenticationStrategy : Delegating to org.springframework.security.web.authentication.session.ChangeSessionIdAuthenticationStrategy@419074cb
2017-05-11 11:51:18.806 DEBUG 10256 --- [qtp424848797-87] w.c.HttpSessionSecurityContextRepository : HttpSession being created as SecurityContext is non-default
2017-05-11 11:51:18.810 DEBUG 10256 --- [qtp424848797-87] w.c.HttpSessionSecurityContextRepository : SecurityContext 'org.springframework.security.core.context.SecurityContextImpl@e0123f1f: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@e0123f1f: Principal: org.springframework.security.core.userdetails.User@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_RUN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_RUN, ROLE_USER' stored to HttpSession: 'org.eclipse.jetty.server.session.Session@6c5d0309
2017-05-11 11:51:18.811 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 12 of 13 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2017-05-11 11:51:18.811 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 13 of 13 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2017-05-11 11:51:18.811 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', GET]
2017-05-11 11:51:18.811 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'POST /api/userprefs' doesn't match 'GET /logout
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', POST]
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/userprefs'; against '/logout'
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', PUT]
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'POST /api/userprefs' doesn't match 'PUT /logout
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', DELETE]
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'POST /api/userprefs' doesn't match 'DELETE /logout
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : No matches found
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.i.FilterSecurityInterceptor : Secure object: FilterInvocation: URL: /api/userprefs; Attributes: [authenticated]
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.i.FilterSecurityInterceptor : Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@e0123f1f: Principal: org.springframework.security.core.userdetails.User@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_RUN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_RUN, ROLE_USER
2017-05-11 11:51:18.818 DEBUG 10256 --- [qtp424848797-87] o.s.s.access.vote.AffirmativeBased : Voter: org.springframework.security.web.access.expression.WebExpressionVoter@721d7b2d, returned: 1
2017-05-11 11:51:18.819 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.i.FilterSecurityInterceptor : Authorization successful
2017-05-11 11:51:18.819 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.i.FilterSecurityInterceptor : RunAsManager did not change Authentication object
2017-05-11 11:51:18.819 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs reached end of additional filter chain; proceeding with original chain
2017-05-11 11:51:18.868 DEBUG 10256 --- [qtp424848797-87] w.c.HttpSessionSecurityContextRepository : SecurityContext 'org.springframework.security.core.context.SecurityContextImpl@e0123f1f: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@e0123f1f: Principal: org.springframework.security.core.userdetails.User@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_RUN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_RUN, ROLE_USER' stored to HttpSession: 'org.eclipse.jetty.server.session.Session@6c5d0309
2017-05-11 11:51:18.916 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.ExceptionTranslationFilter : Chain processed normally
2017-05-11 11:51:18.917 DEBUG 10256 --- [qtp424848797-87] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
我也尝试将注释更改为@PostAuthorize,但我得到了相同的错误,并且没有在方法内部命中断点,因此这与注释在那里这一事实有关,而不是具体的@PreAuthorize。我还尝试了其他几个表达式,包括角色检查和permitAll(),得到了相同的结果。无论经过身份验证的用户是管理员、相关用户(匹配#userPrefs.id==principal.username
)还是其他用户,所有经过身份验证的请求都会返回错误。我还尝试从@RequestMapping中删除products=“application/json”
;添加会消耗=“application/json”
。两者都没有用
这是其他相关代码
UserPrefsDTO:
package com.company.services.rest;
import com.company.server.model.user.preferences.UserPrefs;
import com.company.server.user.prefs.UserPrefsDTO;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
@RequestMapping("/api/userprefs")
public interface UserPrefsRESTController {
@RequestMapping(method = RequestMethod.POST, produces = "application/json")
@PreAuthorize("#userPrefs.id == principal.username or hasRole('ADMIN')")
ResponseEntity<UserPrefsDTO> setUserPrefs(@RequestBody UserPrefs userPrefs);
@RequestMapping(method = RequestMethod.GET, produces = "application/json")
ResponseEntity<UserPrefsDTO> getUserPrefs(@RequestParam String id);
}
package com.company.services.rest;
import com.company.server.model.user.preferences.UserPrefs;
import com.company.server.user.prefs.UserPrefsDTO;
import com.company.server.user.prefs.UserPrefsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserPrefsRESTControllerImpl implements UserPrefsRESTController {
@Autowired
private UserPrefsService userPrefsService;
@Override
public ResponseEntity<UserPrefsDTO> setUserPrefs(UserPrefs userPrefs) {
UserPrefsDTO response;
try {
response = userPrefsService.setUserPrefsValue(userPrefs);
} catch (final IllegalArgumentException e) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);
}
return ResponseEntity.ok(response);
}
@Override
public ResponseEntity<UserPrefsDTO> getUserPrefs(String id) {
return ResponseEntity.ok(userPrefsService.getUserPrefs(id));
}
}
package com.company.server.user.prefs;
import java.io.Serializable;
public class UserPrefsDTO implements Serializable{
private String id;
private String value;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
package com.company.spring.boot;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("password").roles("USER").and()
.withUser("runuser").password("password").roles("USER", "RUN").and()
.withUser("admin").password("password").roles("USER", "RUN", "ADMIN");
}
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin().permitAll().and()
.logout().permitAll().and()
.authorizeRequests()
.anyRequest().authenticated()
.and().csrf().disable()
.httpBasic();
}
}
package com.company.server.model.repositories;
import com.company.server.model.ModelConstants;
import com.company.server.model.user.preferences.UserPrefs;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.security.access.prepost.PreAuthorize;
import javax.persistence.PersistenceContext;
@PersistenceContext(name = ModelConstants.DOMAIN_ID)
@RepositoryRestResource(collectionResourceRel = "UserPrefs", path = "UserPrefs", itemResourceRel="UserPrefs")
public interface UserPrefsRepository extends JpaRepository<UserPrefs, String> {
@Override
@PreAuthorize("hasRole('ADMIN')")
Page<UserPrefs> findAll(Pageable pageable);
@PostAuthorize("returnObject != null && returnObject.id == principal.username or hasRole('ADMIN')")
UserPrefs findById(@Param("id") String id);
}
package com.company.server.model.user.preferences;
import org.springframework.data.rest.core.annotation.HandleBeforeCreate;
import org.springframework.data.rest.core.annotation.HandleBeforeDelete;
import org.springframework.data.rest.core.annotation.HandleBeforeSave;
import org.springframework.data.rest.core.annotation.RepositoryEventHandler;
import org.springframework.security.access.prepost.PreAuthorize;
@RepositoryEventHandler
@SuppressWarnings("unused")
public class UserPrefsEventHandler {
@HandleBeforeCreate
@PreAuthorize("#userPrefs.id == principal.username or hasRole('ADMIN')")
public void checkCreateAuthority(UserPrefs userPrefs) {
System.out.println("checkCreateAuthority");
}
@HandleBeforeSave
@PreAuthorize("#userPrefs.id == principal.username or hasRole('ADMIN')")
public void checkUpdateAuthority(UserPrefs userPrefs) {
System.out.println("checkUpdateAuthority");
}
@HandleBeforeDelete
@PreAuthorize("hasRole('ADMIN')")
public void checkDeleteAuthority(UserPrefs userPrefs) {
System.out.println("checkDeleteAuthority");
}
}
2017-05-11 11:51:18.784 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 1 of 13 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2017-05-11 11:51:18.786 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 2 of 13 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2017-05-11 11:51:18.787 DEBUG 10256 --- [qtp424848797-87] w.c.HttpSessionSecurityContextRepository : No HttpSession currently exists
2017-05-11 11:51:18.787 DEBUG 10256 --- [qtp424848797-87] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: null. A new one will be created.
2017-05-11 11:51:18.790 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 3 of 13 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2017-05-11 11:51:18.790 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.header.writers.HstsHeaderWriter : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@27192c6
2017-05-11 11:51:18.790 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 4 of 13 in additional filter chain; firing Filter: 'LogoutFilter'
2017-05-11 11:51:18.790 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', GET]
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'POST /api/userprefs' doesn't match 'GET /logout
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', POST]
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/userprefs'; against '/logout'
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', PUT]
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'POST /api/userprefs' doesn't match 'PUT /logout
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', DELETE]
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'POST /api/userprefs' doesn't match 'DELETE /logout
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : No matches found
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 5 of 13 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
2017-05-11 11:51:18.792 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/userprefs'; against '/login'
2017-05-11 11:51:18.792 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 6 of 13 in additional filter chain; firing Filter: 'DefaultLoginPageGeneratingFilter'
2017-05-11 11:51:18.792 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 7 of 13 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
2017-05-11 11:51:18.794 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.www.BasicAuthenticationFilter : Basic Authentication Authorization header found for user 'admin'
2017-05-11 11:51:18.795 DEBUG 10256 --- [qtp424848797-87] o.s.s.authentication.ProviderManager : Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
2017-05-11 11:51:18.802 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.www.BasicAuthenticationFilter : Authentication success: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@e0123f1f: Principal: org.springframework.security.core.userdetails.User@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_RUN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_RUN, ROLE_USER
2017-05-11 11:51:18.802 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 8 of 13 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2017-05-11 11:51:18.802 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 9 of 13 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2017-05-11 11:51:18.804 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 10 of 13 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2017-05-11 11:51:18.804 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.AnonymousAuthenticationFilter : SecurityContextHolder not populated with anonymous token, as it already contained: 'org.springframework.security.authentication.UsernamePasswordAuthenticationToken@e0123f1f: Principal: org.springframework.security.core.userdetails.User@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_RUN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_RUN, ROLE_USER'
2017-05-11 11:51:18.804 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 11 of 13 in additional filter chain; firing Filter: 'SessionManagementFilter'
2017-05-11 11:51:18.804 DEBUG 10256 --- [qtp424848797-87] s.CompositeSessionAuthenticationStrategy : Delegating to org.springframework.security.web.authentication.session.ChangeSessionIdAuthenticationStrategy@419074cb
2017-05-11 11:51:18.806 DEBUG 10256 --- [qtp424848797-87] w.c.HttpSessionSecurityContextRepository : HttpSession being created as SecurityContext is non-default
2017-05-11 11:51:18.810 DEBUG 10256 --- [qtp424848797-87] w.c.HttpSessionSecurityContextRepository : SecurityContext 'org.springframework.security.core.context.SecurityContextImpl@e0123f1f: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@e0123f1f: Principal: org.springframework.security.core.userdetails.User@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_RUN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_RUN, ROLE_USER' stored to HttpSession: 'org.eclipse.jetty.server.session.Session@6c5d0309
2017-05-11 11:51:18.811 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 12 of 13 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2017-05-11 11:51:18.811 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 13 of 13 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2017-05-11 11:51:18.811 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', GET]
2017-05-11 11:51:18.811 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'POST /api/userprefs' doesn't match 'GET /logout
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', POST]
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/userprefs'; against '/logout'
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', PUT]
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'POST /api/userprefs' doesn't match 'PUT /logout
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', DELETE]
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'POST /api/userprefs' doesn't match 'DELETE /logout
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : No matches found
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.i.FilterSecurityInterceptor : Secure object: FilterInvocation: URL: /api/userprefs; Attributes: [authenticated]
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.i.FilterSecurityInterceptor : Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@e0123f1f: Principal: org.springframework.security.core.userdetails.User@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_RUN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_RUN, ROLE_USER
2017-05-11 11:51:18.818 DEBUG 10256 --- [qtp424848797-87] o.s.s.access.vote.AffirmativeBased : Voter: org.springframework.security.web.access.expression.WebExpressionVoter@721d7b2d, returned: 1
2017-05-11 11:51:18.819 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.i.FilterSecurityInterceptor : Authorization successful
2017-05-11 11:51:18.819 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.i.FilterSecurityInterceptor : RunAsManager did not change Authentication object
2017-05-11 11:51:18.819 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs reached end of additional filter chain; proceeding with original chain
2017-05-11 11:51:18.868 DEBUG 10256 --- [qtp424848797-87] w.c.HttpSessionSecurityContextRepository : SecurityContext 'org.springframework.security.core.context.SecurityContextImpl@e0123f1f: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@e0123f1f: Principal: org.springframework.security.core.userdetails.User@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_RUN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_RUN, ROLE_USER' stored to HttpSession: 'org.eclipse.jetty.server.session.Session@6c5d0309
2017-05-11 11:51:18.916 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.ExceptionTranslationFilter : Chain processed normally
2017-05-11 11:51:18.917 DEBUG 10256 --- [qtp424848797-87] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
配置:
package com.company.services.rest;
import com.company.server.model.user.preferences.UserPrefs;
import com.company.server.user.prefs.UserPrefsDTO;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
@RequestMapping("/api/userprefs")
public interface UserPrefsRESTController {
@RequestMapping(method = RequestMethod.POST, produces = "application/json")
@PreAuthorize("#userPrefs.id == principal.username or hasRole('ADMIN')")
ResponseEntity<UserPrefsDTO> setUserPrefs(@RequestBody UserPrefs userPrefs);
@RequestMapping(method = RequestMethod.GET, produces = "application/json")
ResponseEntity<UserPrefsDTO> getUserPrefs(@RequestParam String id);
}
package com.company.services.rest;
import com.company.server.model.user.preferences.UserPrefs;
import com.company.server.user.prefs.UserPrefsDTO;
import com.company.server.user.prefs.UserPrefsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserPrefsRESTControllerImpl implements UserPrefsRESTController {
@Autowired
private UserPrefsService userPrefsService;
@Override
public ResponseEntity<UserPrefsDTO> setUserPrefs(UserPrefs userPrefs) {
UserPrefsDTO response;
try {
response = userPrefsService.setUserPrefsValue(userPrefs);
} catch (final IllegalArgumentException e) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);
}
return ResponseEntity.ok(response);
}
@Override
public ResponseEntity<UserPrefsDTO> getUserPrefs(String id) {
return ResponseEntity.ok(userPrefsService.getUserPrefs(id));
}
}
package com.company.server.user.prefs;
import java.io.Serializable;
public class UserPrefsDTO implements Serializable{
private String id;
private String value;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
package com.company.spring.boot;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("password").roles("USER").and()
.withUser("runuser").password("password").roles("USER", "RUN").and()
.withUser("admin").password("password").roles("USER", "RUN", "ADMIN");
}
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin().permitAll().and()
.logout().permitAll().and()
.authorizeRequests()
.anyRequest().authenticated()
.and().csrf().disable()
.httpBasic();
}
}
package com.company.server.model.repositories;
import com.company.server.model.ModelConstants;
import com.company.server.model.user.preferences.UserPrefs;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.security.access.prepost.PreAuthorize;
import javax.persistence.PersistenceContext;
@PersistenceContext(name = ModelConstants.DOMAIN_ID)
@RepositoryRestResource(collectionResourceRel = "UserPrefs", path = "UserPrefs", itemResourceRel="UserPrefs")
public interface UserPrefsRepository extends JpaRepository<UserPrefs, String> {
@Override
@PreAuthorize("hasRole('ADMIN')")
Page<UserPrefs> findAll(Pageable pageable);
@PostAuthorize("returnObject != null && returnObject.id == principal.username or hasRole('ADMIN')")
UserPrefs findById(@Param("id") String id);
}
package com.company.server.model.user.preferences;
import org.springframework.data.rest.core.annotation.HandleBeforeCreate;
import org.springframework.data.rest.core.annotation.HandleBeforeDelete;
import org.springframework.data.rest.core.annotation.HandleBeforeSave;
import org.springframework.data.rest.core.annotation.RepositoryEventHandler;
import org.springframework.security.access.prepost.PreAuthorize;
@RepositoryEventHandler
@SuppressWarnings("unused")
public class UserPrefsEventHandler {
@HandleBeforeCreate
@PreAuthorize("#userPrefs.id == principal.username or hasRole('ADMIN')")
public void checkCreateAuthority(UserPrefs userPrefs) {
System.out.println("checkCreateAuthority");
}
@HandleBeforeSave
@PreAuthorize("#userPrefs.id == principal.username or hasRole('ADMIN')")
public void checkUpdateAuthority(UserPrefs userPrefs) {
System.out.println("checkUpdateAuthority");
}
@HandleBeforeDelete
@PreAuthorize("hasRole('ADMIN')")
public void checkDeleteAuthority(UserPrefs userPrefs) {
System.out.println("checkDeleteAuthority");
}
}
2017-05-11 11:51:18.784 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 1 of 13 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2017-05-11 11:51:18.786 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 2 of 13 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2017-05-11 11:51:18.787 DEBUG 10256 --- [qtp424848797-87] w.c.HttpSessionSecurityContextRepository : No HttpSession currently exists
2017-05-11 11:51:18.787 DEBUG 10256 --- [qtp424848797-87] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: null. A new one will be created.
2017-05-11 11:51:18.790 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 3 of 13 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2017-05-11 11:51:18.790 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.header.writers.HstsHeaderWriter : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@27192c6
2017-05-11 11:51:18.790 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 4 of 13 in additional filter chain; firing Filter: 'LogoutFilter'
2017-05-11 11:51:18.790 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', GET]
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'POST /api/userprefs' doesn't match 'GET /logout
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', POST]
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/userprefs'; against '/logout'
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', PUT]
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'POST /api/userprefs' doesn't match 'PUT /logout
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', DELETE]
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'POST /api/userprefs' doesn't match 'DELETE /logout
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : No matches found
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 5 of 13 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
2017-05-11 11:51:18.792 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/userprefs'; against '/login'
2017-05-11 11:51:18.792 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 6 of 13 in additional filter chain; firing Filter: 'DefaultLoginPageGeneratingFilter'
2017-05-11 11:51:18.792 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 7 of 13 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
2017-05-11 11:51:18.794 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.www.BasicAuthenticationFilter : Basic Authentication Authorization header found for user 'admin'
2017-05-11 11:51:18.795 DEBUG 10256 --- [qtp424848797-87] o.s.s.authentication.ProviderManager : Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
2017-05-11 11:51:18.802 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.www.BasicAuthenticationFilter : Authentication success: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@e0123f1f: Principal: org.springframework.security.core.userdetails.User@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_RUN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_RUN, ROLE_USER
2017-05-11 11:51:18.802 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 8 of 13 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2017-05-11 11:51:18.802 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 9 of 13 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2017-05-11 11:51:18.804 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 10 of 13 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2017-05-11 11:51:18.804 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.AnonymousAuthenticationFilter : SecurityContextHolder not populated with anonymous token, as it already contained: 'org.springframework.security.authentication.UsernamePasswordAuthenticationToken@e0123f1f: Principal: org.springframework.security.core.userdetails.User@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_RUN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_RUN, ROLE_USER'
2017-05-11 11:51:18.804 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 11 of 13 in additional filter chain; firing Filter: 'SessionManagementFilter'
2017-05-11 11:51:18.804 DEBUG 10256 --- [qtp424848797-87] s.CompositeSessionAuthenticationStrategy : Delegating to org.springframework.security.web.authentication.session.ChangeSessionIdAuthenticationStrategy@419074cb
2017-05-11 11:51:18.806 DEBUG 10256 --- [qtp424848797-87] w.c.HttpSessionSecurityContextRepository : HttpSession being created as SecurityContext is non-default
2017-05-11 11:51:18.810 DEBUG 10256 --- [qtp424848797-87] w.c.HttpSessionSecurityContextRepository : SecurityContext 'org.springframework.security.core.context.SecurityContextImpl@e0123f1f: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@e0123f1f: Principal: org.springframework.security.core.userdetails.User@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_RUN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_RUN, ROLE_USER' stored to HttpSession: 'org.eclipse.jetty.server.session.Session@6c5d0309
2017-05-11 11:51:18.811 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 12 of 13 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2017-05-11 11:51:18.811 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 13 of 13 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2017-05-11 11:51:18.811 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', GET]
2017-05-11 11:51:18.811 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'POST /api/userprefs' doesn't match 'GET /logout
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', POST]
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/userprefs'; against '/logout'
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', PUT]
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'POST /api/userprefs' doesn't match 'PUT /logout
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', DELETE]
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'POST /api/userprefs' doesn't match 'DELETE /logout
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : No matches found
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.i.FilterSecurityInterceptor : Secure object: FilterInvocation: URL: /api/userprefs; Attributes: [authenticated]
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.i.FilterSecurityInterceptor : Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@e0123f1f: Principal: org.springframework.security.core.userdetails.User@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_RUN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_RUN, ROLE_USER
2017-05-11 11:51:18.818 DEBUG 10256 --- [qtp424848797-87] o.s.s.access.vote.AffirmativeBased : Voter: org.springframework.security.web.access.expression.WebExpressionVoter@721d7b2d, returned: 1
2017-05-11 11:51:18.819 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.i.FilterSecurityInterceptor : Authorization successful
2017-05-11 11:51:18.819 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.i.FilterSecurityInterceptor : RunAsManager did not change Authentication object
2017-05-11 11:51:18.819 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs reached end of additional filter chain; proceeding with original chain
2017-05-11 11:51:18.868 DEBUG 10256 --- [qtp424848797-87] w.c.HttpSessionSecurityContextRepository : SecurityContext 'org.springframework.security.core.context.SecurityContextImpl@e0123f1f: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@e0123f1f: Principal: org.springframework.security.core.userdetails.User@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_RUN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_RUN, ROLE_USER' stored to HttpSession: 'org.eclipse.jetty.server.session.Session@6c5d0309
2017-05-11 11:51:18.916 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.ExceptionTranslationFilter : Chain processed normally
2017-05-11 11:51:18.917 DEBUG 10256 --- [qtp424848797-87] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
userprefsrespository:
package com.company.services.rest;
import com.company.server.model.user.preferences.UserPrefs;
import com.company.server.user.prefs.UserPrefsDTO;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
@RequestMapping("/api/userprefs")
public interface UserPrefsRESTController {
@RequestMapping(method = RequestMethod.POST, produces = "application/json")
@PreAuthorize("#userPrefs.id == principal.username or hasRole('ADMIN')")
ResponseEntity<UserPrefsDTO> setUserPrefs(@RequestBody UserPrefs userPrefs);
@RequestMapping(method = RequestMethod.GET, produces = "application/json")
ResponseEntity<UserPrefsDTO> getUserPrefs(@RequestParam String id);
}
package com.company.services.rest;
import com.company.server.model.user.preferences.UserPrefs;
import com.company.server.user.prefs.UserPrefsDTO;
import com.company.server.user.prefs.UserPrefsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserPrefsRESTControllerImpl implements UserPrefsRESTController {
@Autowired
private UserPrefsService userPrefsService;
@Override
public ResponseEntity<UserPrefsDTO> setUserPrefs(UserPrefs userPrefs) {
UserPrefsDTO response;
try {
response = userPrefsService.setUserPrefsValue(userPrefs);
} catch (final IllegalArgumentException e) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);
}
return ResponseEntity.ok(response);
}
@Override
public ResponseEntity<UserPrefsDTO> getUserPrefs(String id) {
return ResponseEntity.ok(userPrefsService.getUserPrefs(id));
}
}
package com.company.server.user.prefs;
import java.io.Serializable;
public class UserPrefsDTO implements Serializable{
private String id;
private String value;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
package com.company.spring.boot;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("password").roles("USER").and()
.withUser("runuser").password("password").roles("USER", "RUN").and()
.withUser("admin").password("password").roles("USER", "RUN", "ADMIN");
}
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin().permitAll().and()
.logout().permitAll().and()
.authorizeRequests()
.anyRequest().authenticated()
.and().csrf().disable()
.httpBasic();
}
}
package com.company.server.model.repositories;
import com.company.server.model.ModelConstants;
import com.company.server.model.user.preferences.UserPrefs;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.security.access.prepost.PreAuthorize;
import javax.persistence.PersistenceContext;
@PersistenceContext(name = ModelConstants.DOMAIN_ID)
@RepositoryRestResource(collectionResourceRel = "UserPrefs", path = "UserPrefs", itemResourceRel="UserPrefs")
public interface UserPrefsRepository extends JpaRepository<UserPrefs, String> {
@Override
@PreAuthorize("hasRole('ADMIN')")
Page<UserPrefs> findAll(Pageable pageable);
@PostAuthorize("returnObject != null && returnObject.id == principal.username or hasRole('ADMIN')")
UserPrefs findById(@Param("id") String id);
}
package com.company.server.model.user.preferences;
import org.springframework.data.rest.core.annotation.HandleBeforeCreate;
import org.springframework.data.rest.core.annotation.HandleBeforeDelete;
import org.springframework.data.rest.core.annotation.HandleBeforeSave;
import org.springframework.data.rest.core.annotation.RepositoryEventHandler;
import org.springframework.security.access.prepost.PreAuthorize;
@RepositoryEventHandler
@SuppressWarnings("unused")
public class UserPrefsEventHandler {
@HandleBeforeCreate
@PreAuthorize("#userPrefs.id == principal.username or hasRole('ADMIN')")
public void checkCreateAuthority(UserPrefs userPrefs) {
System.out.println("checkCreateAuthority");
}
@HandleBeforeSave
@PreAuthorize("#userPrefs.id == principal.username or hasRole('ADMIN')")
public void checkUpdateAuthority(UserPrefs userPrefs) {
System.out.println("checkUpdateAuthority");
}
@HandleBeforeDelete
@PreAuthorize("hasRole('ADMIN')")
public void checkDeleteAuthority(UserPrefs userPrefs) {
System.out.println("checkDeleteAuthority");
}
}
2017-05-11 11:51:18.784 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 1 of 13 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2017-05-11 11:51:18.786 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 2 of 13 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2017-05-11 11:51:18.787 DEBUG 10256 --- [qtp424848797-87] w.c.HttpSessionSecurityContextRepository : No HttpSession currently exists
2017-05-11 11:51:18.787 DEBUG 10256 --- [qtp424848797-87] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: null. A new one will be created.
2017-05-11 11:51:18.790 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 3 of 13 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2017-05-11 11:51:18.790 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.header.writers.HstsHeaderWriter : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@27192c6
2017-05-11 11:51:18.790 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 4 of 13 in additional filter chain; firing Filter: 'LogoutFilter'
2017-05-11 11:51:18.790 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', GET]
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'POST /api/userprefs' doesn't match 'GET /logout
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', POST]
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/userprefs'; against '/logout'
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', PUT]
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'POST /api/userprefs' doesn't match 'PUT /logout
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', DELETE]
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'POST /api/userprefs' doesn't match 'DELETE /logout
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : No matches found
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 5 of 13 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
2017-05-11 11:51:18.792 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/userprefs'; against '/login'
2017-05-11 11:51:18.792 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 6 of 13 in additional filter chain; firing Filter: 'DefaultLoginPageGeneratingFilter'
2017-05-11 11:51:18.792 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 7 of 13 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
2017-05-11 11:51:18.794 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.www.BasicAuthenticationFilter : Basic Authentication Authorization header found for user 'admin'
2017-05-11 11:51:18.795 DEBUG 10256 --- [qtp424848797-87] o.s.s.authentication.ProviderManager : Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
2017-05-11 11:51:18.802 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.www.BasicAuthenticationFilter : Authentication success: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@e0123f1f: Principal: org.springframework.security.core.userdetails.User@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_RUN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_RUN, ROLE_USER
2017-05-11 11:51:18.802 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 8 of 13 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2017-05-11 11:51:18.802 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 9 of 13 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2017-05-11 11:51:18.804 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 10 of 13 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2017-05-11 11:51:18.804 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.AnonymousAuthenticationFilter : SecurityContextHolder not populated with anonymous token, as it already contained: 'org.springframework.security.authentication.UsernamePasswordAuthenticationToken@e0123f1f: Principal: org.springframework.security.core.userdetails.User@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_RUN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_RUN, ROLE_USER'
2017-05-11 11:51:18.804 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 11 of 13 in additional filter chain; firing Filter: 'SessionManagementFilter'
2017-05-11 11:51:18.804 DEBUG 10256 --- [qtp424848797-87] s.CompositeSessionAuthenticationStrategy : Delegating to org.springframework.security.web.authentication.session.ChangeSessionIdAuthenticationStrategy@419074cb
2017-05-11 11:51:18.806 DEBUG 10256 --- [qtp424848797-87] w.c.HttpSessionSecurityContextRepository : HttpSession being created as SecurityContext is non-default
2017-05-11 11:51:18.810 DEBUG 10256 --- [qtp424848797-87] w.c.HttpSessionSecurityContextRepository : SecurityContext 'org.springframework.security.core.context.SecurityContextImpl@e0123f1f: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@e0123f1f: Principal: org.springframework.security.core.userdetails.User@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_RUN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_RUN, ROLE_USER' stored to HttpSession: 'org.eclipse.jetty.server.session.Session@6c5d0309
2017-05-11 11:51:18.811 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 12 of 13 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2017-05-11 11:51:18.811 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 13 of 13 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2017-05-11 11:51:18.811 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', GET]
2017-05-11 11:51:18.811 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'POST /api/userprefs' doesn't match 'GET /logout
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', POST]
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/userprefs'; against '/logout'
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', PUT]
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'POST /api/userprefs' doesn't match 'PUT /logout
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', DELETE]
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'POST /api/userprefs' doesn't match 'DELETE /logout
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : No matches found
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.i.FilterSecurityInterceptor : Secure object: FilterInvocation: URL: /api/userprefs; Attributes: [authenticated]
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.i.FilterSecurityInterceptor : Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@e0123f1f: Principal: org.springframework.security.core.userdetails.User@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_RUN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_RUN, ROLE_USER
2017-05-11 11:51:18.818 DEBUG 10256 --- [qtp424848797-87] o.s.s.access.vote.AffirmativeBased : Voter: org.springframework.security.web.access.expression.WebExpressionVoter@721d7b2d, returned: 1
2017-05-11 11:51:18.819 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.i.FilterSecurityInterceptor : Authorization successful
2017-05-11 11:51:18.819 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.i.FilterSecurityInterceptor : RunAsManager did not change Authentication object
2017-05-11 11:51:18.819 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs reached end of additional filter chain; proceeding with original chain
2017-05-11 11:51:18.868 DEBUG 10256 --- [qtp424848797-87] w.c.HttpSessionSecurityContextRepository : SecurityContext 'org.springframework.security.core.context.SecurityContextImpl@e0123f1f: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@e0123f1f: Principal: org.springframework.security.core.userdetails.User@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_RUN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_RUN, ROLE_USER' stored to HttpSession: 'org.eclipse.jetty.server.session.Session@6c5d0309
2017-05-11 11:51:18.916 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.ExceptionTranslationFilter : Chain processed normally
2017-05-11 11:51:18.917 DEBUG 10256 --- [qtp424848797-87] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
注意:上面的类是通过另一个配置文件中的bean添加的:
@Bean
UserPrefsEventHandler userPrefsEventHandler() {
return new UserPrefsEventHandler();
}
是什么导致415错误
更新-Spring安全调试日志:
package com.company.services.rest;
import com.company.server.model.user.preferences.UserPrefs;
import com.company.server.user.prefs.UserPrefsDTO;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
@RequestMapping("/api/userprefs")
public interface UserPrefsRESTController {
@RequestMapping(method = RequestMethod.POST, produces = "application/json")
@PreAuthorize("#userPrefs.id == principal.username or hasRole('ADMIN')")
ResponseEntity<UserPrefsDTO> setUserPrefs(@RequestBody UserPrefs userPrefs);
@RequestMapping(method = RequestMethod.GET, produces = "application/json")
ResponseEntity<UserPrefsDTO> getUserPrefs(@RequestParam String id);
}
package com.company.services.rest;
import com.company.server.model.user.preferences.UserPrefs;
import com.company.server.user.prefs.UserPrefsDTO;
import com.company.server.user.prefs.UserPrefsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserPrefsRESTControllerImpl implements UserPrefsRESTController {
@Autowired
private UserPrefsService userPrefsService;
@Override
public ResponseEntity<UserPrefsDTO> setUserPrefs(UserPrefs userPrefs) {
UserPrefsDTO response;
try {
response = userPrefsService.setUserPrefsValue(userPrefs);
} catch (final IllegalArgumentException e) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);
}
return ResponseEntity.ok(response);
}
@Override
public ResponseEntity<UserPrefsDTO> getUserPrefs(String id) {
return ResponseEntity.ok(userPrefsService.getUserPrefs(id));
}
}
package com.company.server.user.prefs;
import java.io.Serializable;
public class UserPrefsDTO implements Serializable{
private String id;
private String value;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
package com.company.spring.boot;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("password").roles("USER").and()
.withUser("runuser").password("password").roles("USER", "RUN").and()
.withUser("admin").password("password").roles("USER", "RUN", "ADMIN");
}
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin().permitAll().and()
.logout().permitAll().and()
.authorizeRequests()
.anyRequest().authenticated()
.and().csrf().disable()
.httpBasic();
}
}
package com.company.server.model.repositories;
import com.company.server.model.ModelConstants;
import com.company.server.model.user.preferences.UserPrefs;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.security.access.prepost.PreAuthorize;
import javax.persistence.PersistenceContext;
@PersistenceContext(name = ModelConstants.DOMAIN_ID)
@RepositoryRestResource(collectionResourceRel = "UserPrefs", path = "UserPrefs", itemResourceRel="UserPrefs")
public interface UserPrefsRepository extends JpaRepository<UserPrefs, String> {
@Override
@PreAuthorize("hasRole('ADMIN')")
Page<UserPrefs> findAll(Pageable pageable);
@PostAuthorize("returnObject != null && returnObject.id == principal.username or hasRole('ADMIN')")
UserPrefs findById(@Param("id") String id);
}
package com.company.server.model.user.preferences;
import org.springframework.data.rest.core.annotation.HandleBeforeCreate;
import org.springframework.data.rest.core.annotation.HandleBeforeDelete;
import org.springframework.data.rest.core.annotation.HandleBeforeSave;
import org.springframework.data.rest.core.annotation.RepositoryEventHandler;
import org.springframework.security.access.prepost.PreAuthorize;
@RepositoryEventHandler
@SuppressWarnings("unused")
public class UserPrefsEventHandler {
@HandleBeforeCreate
@PreAuthorize("#userPrefs.id == principal.username or hasRole('ADMIN')")
public void checkCreateAuthority(UserPrefs userPrefs) {
System.out.println("checkCreateAuthority");
}
@HandleBeforeSave
@PreAuthorize("#userPrefs.id == principal.username or hasRole('ADMIN')")
public void checkUpdateAuthority(UserPrefs userPrefs) {
System.out.println("checkUpdateAuthority");
}
@HandleBeforeDelete
@PreAuthorize("hasRole('ADMIN')")
public void checkDeleteAuthority(UserPrefs userPrefs) {
System.out.println("checkDeleteAuthority");
}
}
2017-05-11 11:51:18.784 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 1 of 13 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2017-05-11 11:51:18.786 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 2 of 13 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2017-05-11 11:51:18.787 DEBUG 10256 --- [qtp424848797-87] w.c.HttpSessionSecurityContextRepository : No HttpSession currently exists
2017-05-11 11:51:18.787 DEBUG 10256 --- [qtp424848797-87] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: null. A new one will be created.
2017-05-11 11:51:18.790 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 3 of 13 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2017-05-11 11:51:18.790 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.header.writers.HstsHeaderWriter : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@27192c6
2017-05-11 11:51:18.790 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 4 of 13 in additional filter chain; firing Filter: 'LogoutFilter'
2017-05-11 11:51:18.790 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', GET]
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'POST /api/userprefs' doesn't match 'GET /logout
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', POST]
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/userprefs'; against '/logout'
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', PUT]
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'POST /api/userprefs' doesn't match 'PUT /logout
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', DELETE]
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'POST /api/userprefs' doesn't match 'DELETE /logout
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : No matches found
2017-05-11 11:51:18.791 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 5 of 13 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
2017-05-11 11:51:18.792 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/userprefs'; against '/login'
2017-05-11 11:51:18.792 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 6 of 13 in additional filter chain; firing Filter: 'DefaultLoginPageGeneratingFilter'
2017-05-11 11:51:18.792 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 7 of 13 in additional filter chain; firing Filter: 'BasicAuthenticationFilter'
2017-05-11 11:51:18.794 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.www.BasicAuthenticationFilter : Basic Authentication Authorization header found for user 'admin'
2017-05-11 11:51:18.795 DEBUG 10256 --- [qtp424848797-87] o.s.s.authentication.ProviderManager : Authentication attempt using org.springframework.security.authentication.dao.DaoAuthenticationProvider
2017-05-11 11:51:18.802 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.www.BasicAuthenticationFilter : Authentication success: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@e0123f1f: Principal: org.springframework.security.core.userdetails.User@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_RUN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_RUN, ROLE_USER
2017-05-11 11:51:18.802 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 8 of 13 in additional filter chain; firing Filter: 'RequestCacheAwareFilter'
2017-05-11 11:51:18.802 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 9 of 13 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter'
2017-05-11 11:51:18.804 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 10 of 13 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter'
2017-05-11 11:51:18.804 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.AnonymousAuthenticationFilter : SecurityContextHolder not populated with anonymous token, as it already contained: 'org.springframework.security.authentication.UsernamePasswordAuthenticationToken@e0123f1f: Principal: org.springframework.security.core.userdetails.User@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_RUN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_RUN, ROLE_USER'
2017-05-11 11:51:18.804 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 11 of 13 in additional filter chain; firing Filter: 'SessionManagementFilter'
2017-05-11 11:51:18.804 DEBUG 10256 --- [qtp424848797-87] s.CompositeSessionAuthenticationStrategy : Delegating to org.springframework.security.web.authentication.session.ChangeSessionIdAuthenticationStrategy@419074cb
2017-05-11 11:51:18.806 DEBUG 10256 --- [qtp424848797-87] w.c.HttpSessionSecurityContextRepository : HttpSession being created as SecurityContext is non-default
2017-05-11 11:51:18.810 DEBUG 10256 --- [qtp424848797-87] w.c.HttpSessionSecurityContextRepository : SecurityContext 'org.springframework.security.core.context.SecurityContextImpl@e0123f1f: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@e0123f1f: Principal: org.springframework.security.core.userdetails.User@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_RUN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_RUN, ROLE_USER' stored to HttpSession: 'org.eclipse.jetty.server.session.Session@6c5d0309
2017-05-11 11:51:18.811 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 12 of 13 in additional filter chain; firing Filter: 'ExceptionTranslationFilter'
2017-05-11 11:51:18.811 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs at position 13 of 13 in additional filter chain; firing Filter: 'FilterSecurityInterceptor'
2017-05-11 11:51:18.811 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', GET]
2017-05-11 11:51:18.811 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'POST /api/userprefs' doesn't match 'GET /logout
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', POST]
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/api/userprefs'; against '/logout'
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', PUT]
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'POST /api/userprefs' doesn't match 'PUT /logout
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : Trying to match using Ant [pattern='/logout', DELETE]
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'POST /api/userprefs' doesn't match 'DELETE /logout
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.web.util.matcher.OrRequestMatcher : No matches found
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.i.FilterSecurityInterceptor : Secure object: FilterInvocation: URL: /api/userprefs; Attributes: [authenticated]
2017-05-11 11:51:18.812 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.i.FilterSecurityInterceptor : Previously Authenticated: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@e0123f1f: Principal: org.springframework.security.core.userdetails.User@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_RUN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_RUN, ROLE_USER
2017-05-11 11:51:18.818 DEBUG 10256 --- [qtp424848797-87] o.s.s.access.vote.AffirmativeBased : Voter: org.springframework.security.web.access.expression.WebExpressionVoter@721d7b2d, returned: 1
2017-05-11 11:51:18.819 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.i.FilterSecurityInterceptor : Authorization successful
2017-05-11 11:51:18.819 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.i.FilterSecurityInterceptor : RunAsManager did not change Authentication object
2017-05-11 11:51:18.819 DEBUG 10256 --- [qtp424848797-87] o.s.security.web.FilterChainProxy : /api/userprefs reached end of additional filter chain; proceeding with original chain
2017-05-11 11:51:18.868 DEBUG 10256 --- [qtp424848797-87] w.c.HttpSessionSecurityContextRepository : SecurityContext 'org.springframework.security.core.context.SecurityContextImpl@e0123f1f: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@e0123f1f: Principal: org.springframework.security.core.userdetails.User@586034f: Username: admin; Password: [PROTECTED]; Enabled: true; AccountNonExpired: true; credentialsNonExpired: true; AccountNonLocked: true; Granted Authorities: ROLE_ADMIN,ROLE_RUN,ROLE_USER; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ADMIN, ROLE_RUN, ROLE_USER' stored to HttpSession: 'org.eclipse.jetty.server.session.Session@6c5d0309
2017-05-11 11:51:18.916 DEBUG 10256 --- [qtp424848797-87] o.s.s.w.a.ExceptionTranslationFilter : Chain processed normally
2017-05-11 11:51:18.917 DEBUG 10256 --- [qtp424848797-87] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
奇怪的是,我在调试日志中没有看到任何与错误相关的内容,尽管我可能忽略了一些东西
更新2-“多部分/表单数据”与“应用程序/json”
我一直以“多部分/表单数据”的形式提交请求,这会产生错误。当我将其作为“application/json”发送时,请求成功。当@PreAuthorize注释不存在时,请求作为“多部分/表单数据”提交时工作正常,这一事实仍然让我感到困惑。虽然以“application/json”的形式发送是解决我的问题的一个足够的解决方案,但问题仍然是这是一个问题的原因。您是否有任何带有
HttpMediaTypeNotSupportedException
的日志?也许堆栈跟踪会给我们提供更多的信息?不幸的是,除了发布的日志之外,没有其他日志生成,我不确定需要编辑哪些日志级别设置才能获得这些信息。