[오류/해결][Spring] isAnonymous()와 isAuthenticated()가 잘 동작하지 않음

이신영·2023년 3월 14일
0

오류 모음집

목록 보기
11/24
post-thumbnail

오류상황

: spring security로 로그인 관리를 만들었고

                .formLogin()
                .loginPage("/user/login")
                .defaultSuccessUrl("/board/list")
                //로그아웃 페이지 설정
                .and()
                .logout()
                .logoutRequestMatcher(new AntPathRequestMatcher("/user/logout"))
                .logoutSuccessUrl("/board/list")
                .invalidateHttpSession(true);

뷰에다가

    <a  sec:authorize="isAnonymous()" th:href="@{/user/login}">로그인</a>
    <a  sec:authorize="isAuthenticated()" th:href="@{/user/logout}">로그아웃</a>

이거 써넣어서 로그인안하면 로그아웃버튼이 가려지게, 로그인하면 로그아웃버튼이 가려져야하는데 제대로 작동하지 않음

defaultSuccessUrl()이 제대로 작동했다는건 세션이 생긴건데 아마 sec:authorize가 잘못된게 아닐까? 하는 생각


와 스프링 시큐리티 진짜 어렵다.. 너무 자동적으로 세션을 생성해주고 그래서 너무편리하니까 오히려 구조이해에 독이 되는것같은 느낌

2023-04-18 코맨트

이거는 UserDetail을 제대로 사용하지 않아서 생긴 문제같다. 내가 잘못 이해한 부분은, defaultSuccessUrl()이 제대로 작동했다는것 = 세션이 생긴것 으로 판단하고 sec:authorize가 잘못된게 아닐까? 라는 트러블슈팅이지만,

이 시점에 내가 구현해둔건 회원가입 db뿐이고 사용자정보를 가져오는 부분을 override만 했지 제대로 로직을 구현하지 않아서 생긴 오류이다.(코드는 어디갔는지 모르겠음)

public class UserSecurityService implements UserDetailsService {

    private final UserRepository userRepository;

    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException{
        Optional<Member> _member = this.userRepository.findByusername(username);
        if(_member.isEmpty()){
            throw new UsernameNotFoundException("사용자를 찾을 수 없습니다.");
        }
        //회원정보
        Member member = _member.get();
        //권한정보
        List<GrantedAuthority> authorities = new ArrayList<>();

        //사용자권한처리
        if("admin".equals(username)){
            authorities.add(new SimpleGrantedAuthority(UserRole.ADMIN.getValue()));
        } else {
            authorities.add(new SimpleGrantedAuthority(UserRole.USER.getValue()));
        }

        return new User(member.getUsername(), member.getPassword(), authorities);
    }
  • UserDetails에 저장될 사용자정보를 커스텀하기 위해서 UserDetailsService를 implements함

조금 더 설명하자면,
spring security에서는 UserDetails라는 사용자 정보를 담아두는 인터페이스가 있는데 나는 UserDetailsService를 implements만 했지 UserDetails를 리턴해줄 loadUserByUsername을 구현하지 않았다. 때문에 sec:authorize()는 제대로 작동했지만 USerDetails를 통해 권한을 리턴받지못하여 버튼이 보이지 않던게 이유다.


후기

오류에 대한 게시글을 다시 정리하고있는데 지금 돌아보니까 spring sercurity에 대한 개념이 부족한 상태로 진행했었던거같다. 혹시 또 볼수있으니까 내가 지금 이해한 spring security를 통해 로그인을 하는건 여러 방식이 있는데 그 중에 내가 구현한 방법은 다음과 같다.

  1. spring security config파일로 로그인 폼을 인식시킴
  2. 로그인 폼에서 전달한 값을 UserDetailsServiceloadUserByUsername으로 인증함
  3. UserDetails 인터페이스는 사용자정보를 제공하는 역할인데 커스텀이 가능함. User 클래스를 통해 사용자정보를 저장하는걸 다른식으로 커스텀할수있음.(현재 진행하는 프로젝트도 다른식으로 커스텀중)
  4. 로그인 폼에서 전달된 값이 맞다면 spring sercurity가 세션을 생성하고 config파일에 있는 url로 이동시킴

물론 이건 spring sercurity의 일부 기능을 이용해서 사용한거고 이외에도 다양한 기능이 제공되어 디테일을 여러가지 추가할수있는거같다.

이게 오류를 포스팅하는 순기능이 아닐까? 사소한 오류들이라도 간단하게 해결하는 문제들이 많이 있는데 그중에도 야매로 해결되는부분도 있을거같다. 앞으로 오류가 발생하면 일단 올려야겠다 ㅎㅎ;


미래의 코멘트

이거 진짜 이당시에는 영영 해결못할 난제같았는데 지금 다시보니까 spring security에 대해 전반적인 구조를 알게되니 오류의 이유를 알게되어서 기쁘다! 성장했다~ 😂

profile
후회하지 않는 사람이 되자 🔥

0개의 댓글