Spring security Spring Security';s@PreAuthorize导致415“;“不支持的媒体类型”;错误

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

我在应用程序中通过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.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
的日志?也许堆栈跟踪会给我们提供更多的信息?不幸的是,除了发布的日志之外,没有其他日志生成,我不确定需要编辑哪些日志级别设置才能获得这些信息。