package demo; import demo.xauth.XAuthTokenConfigurer; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.context.web.SpringBootServletInitializer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.SecurityConfigurer; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; 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; import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.web.DefaultSecurityFilterChain; import org.springframework.web.bind.annotation.*; import java.util.*; import java.util.concurrent.ConcurrentHashMap; @ComponentScan @EnableAutoConfiguration public class Application extends SpringBootServletInitializer { private static Class<Application> entryPointClass = Application.class; public static void main(String[] args) { SpringApplication.run(entryPointClass, args); } @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(entryPointClass); } } @EnableWebMvcSecurity @EnableWebSecurity(debug = false) @Configuration @Order class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable(); http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); String[] restEndpointsToSecure = { "news"}; for (String endpoint : restEndpointsToSecure) { http.authorizeRequests().antMatchers("/" + endpoint + "/**").hasRole(CustomUserDetailsService.ROLE_USER); } SecurityConfigurer<DefaultSecurityFilterChain, HttpSecurity> securityConfigurerAdapter = new XAuthTokenConfigurer(userDetailsServiceBean()); http.apply(securityConfigurerAdapter); } @Override protected void configure(AuthenticationManagerBuilder authManagerBuilder) throws Exception { authManagerBuilder.userDetailsService(new CustomUserDetailsService()); } @Bean @Override public UserDetailsService userDetailsServiceBean() throws Exception { return super.userDetailsServiceBean(); } @Bean @Override public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } } class CustomUserDetailsService implements UserDetailsService { public static final String ROLE_ADMIN = "ADMIN"; public static final String ROLE_USER = "USER"; @SuppressWarnings("serial") static class SimpleUserDetails implements UserDetails { private String username; private String password; private boolean enabled = true; private Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>(); public SimpleUserDetails(String username, String pw, String... extraRoles) { this.username = username; this.password = pw; // setup roles Set<String> roles = new HashSet<String>(); roles.addAll(Arrays.<String>asList(null == extraRoles ? new String[0] : extraRoles)); // export them as part of authorities for (String r : roles) { authorities.add(new SimpleGrantedAuthority(role(r))); } } public String toString() { return "{enabled:" + isEnabled() + ", username:'" + getUsername() + "', password:'" + getPassword() + "'}"; } @Override public boolean isEnabled() { return this.enabled; } @Override public boolean isCredentialsNonExpired() { return this.enabled; } @Override public boolean isAccountNonLocked() { return this.enabled; } @Override public boolean isAccountNonExpired() { return this.enabled; } @Override public String getUsername() { return this.username; } @Override public String getPassword() { return this.password; } private String role(String i) { return "ROLE_" + i; } @Override public Collection<? extends GrantedAuthority> getAuthorities() { return this.authorities; } } List<UserDetails> details = Arrays.<UserDetails>asList(new SimpleUserDetails("user", "user", ROLE_USER), new SimpleUserDetails("admin", "admin", ROLE_USER, ROLE_ADMIN)); @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { for (UserDetails details : this.details) if (details.getUsername().equalsIgnoreCase(username)) return details; return null; } } @RestController class NewsController { Map<Long, NewsEntry> entries = new ConcurrentHashMap<Long, NewsEntry>(); @RequestMapping("/news") Collection<NewsEntry> entries() { return this.entries.values(); } @RequestMapping(value = "/news/{id}", method = RequestMethod.DELETE) NewsEntry remove(@PathVariable Long id) { return this.entries.remove(id); } @RequestMapping(value = "/news/{id}", method = RequestMethod.GET) NewsEntry entry(@PathVariable Long id) { return this.entries.get(id); } @RequestMapping(value = "/news/{id}", method = RequestMethod.POST) NewsEntry update(@RequestBody NewsEntry news) { this.entries.put(news.getId(), news); return news; } @RequestMapping(value = "/news", method = RequestMethod.POST) NewsEntry add(@RequestBody NewsEntry news) { long id = 10 + new Random().nextInt(99); news.setId(id); this.entries.put(id, news); return news; } NewsController() { for (long i = 0; i < 5; i++) this.entries.put(i, new NewsEntry(i, "Title #" + i)); } public static class NewsEntry { private long id; private String content; public NewsEntry() {} public NewsEntry(long id, String b) { this.id = id; this.content = b; } public long getId() { return this.id; } public String getContent() { return this.content; } public void setId(long id) { this.id = id; } public void setContent(String content) { this.content = content; } } }