1.의의
2.공통 내장 표현식


3.구현
http.authorizeRequests()
.requestMatchers(PathRequest.toStaticResources().atCommonLocations()).access("permitAll")
.antMatchers("/").access("permitAll")
.antMatchers("/auth/login").access("permitAll")
.antMatchers("/user/register", "/user/registerSuccess").access("permitAll")
//사용자가 익명 또는 remember-me 사용자가 그리고 admin 아닌 경우 true를 반환한다.
.antMatchers("/codegroup/**").access("isFullyAuthenticated() and hasRole('ADMIN')")
.antMatchers("/codedetail/**").access("hasIpAddress('127.0.0.1') and hasRole('ADMIN')")
.antMatchers("/board/list", "/board/read").access("permitAll")
.antMatchers("/board/register", "/board/modify").access("isRememberMe() and hasRole('MEMBER')")
.antMatchers("/board/remove").access("hasAnyRole('MEMBER', 'ADMIN')")
.antMatchers("/notice/list", "/notice/read").access("permitAll")
.antMatchers("/notice/register", "/notice/modify", "/notice/remove").access("hasRole('ADMIN')")
.anyRequest().authenticated();
4.경로 변수와 Principal 객체(ch803a)
http.authorizeRequests()
.requestMatchers(PathRequest.toStaticResources().atCommonLocations()).access("permitAll")
.antMatchers("/").access("permitAll")
.antMatchers("/auth/login").access("permitAll")
.antMatchers("/user/register", "/user/registerSuccess").access("permitAll")
.antMatchers("/codegroup/**").access("isFullyAuthenticated() and hasRole('ADMIN')")
.antMatchers("/codedetail/**").access("hasIpAddress('127.0.0.1') and hasRole('ADMIN')")
.antMatchers("/board/list", "/board/read").access("permitAll")
.antMatchers("/board/register", "/board/modify").access("isRememberMe() and hasRole('MEMBER')")
//웹 경로 변수({username}) 와 로그인한 현재 사용자 정보(principal.username)을 사용하여 보안을 정밀하게 설정할 수 있다.
.antMatchers("/board/remove/{username}").access("isAuthenticated() and (hasRole('ADMIN') or (#username == principal.username))")
.antMatchers("/notice/list", "/notice/read").access("permitAll")
.antMatchers("/notice/register", "/notice/modify", "/notice/remove").access("hasRole('ADMIN')")
.anyRequest().authenticated();