Spring Security Login - Софтуерен университет

Spring Security Login - Софтуерен университет

+ Нов въпрос
ibosev avatar ibosev 54 Точки

Spring Security Login

Здравейте,

имам въпрос относно Spring Security. Така както го разбирам, с конфигуирацията, която беше показана на лекцията, нямаме достъп до post заявката, която правим за логин на даден юзър - спринг си прави магиите отзад и връща UserDetails, не можем да сложим @PostMapping анотация в контролера и да оперираме със сесията или каквото и да е. В контролерите имаме достъп до Principal, който държи само username.

Конкретно въпросът ми е как при логин да запазя в сесията (или другаде) друга информация от юзъра, която се държи в ентитито - например кога се е регистрирал, рождена дата или друго? Да кажем, че искам в navbar-а, след успешен login, да се изписва Hello, {fullName}, което го няма в Principal и трябва да правя нова завка към базата. 

Тагове:
0
Java MVC Frameworks - Spring
TeodorDimitrov avatar TeodorDimitrov SoftUni Team Trainer 45 Точки
Best Answer

Има лесен начин да вземеш твоят user без да посягаш към Session обекта.

В контролера:
 

   @GetMapping("/")
    public String getHomePage(Authentication authentication){
        User user = (User) authentication.getPrincipal();
        System.out.println(user.getUsername());
        System.out.println(user.getId());
        return "home";
    }

В Thymeleaf:
 

<div th:text="${#authentication.getPrincipal().getId()}"></div>

Важното тук е да използваш Thymeleaf Security.

Двете парчета код работят независимо едно от друго. Важното е къде ти трябва да използваш User-a.

1
23/03/2017 11:45:22
ibosev avatar ibosev 54 Точки

Искаш да кажеш, че като кастна Principal -> (User), ще мога да му достъпя другите полета на ентитито? Например дата на регистрация, пълното име и т.н.

Едит: Тествах го и работи! 

0
23/03/2017 15:05:52
TeodorDimitrov avatar TeodorDimitrov SoftUni Team Trainer 45 Точки

Точно така. И в thymeleaf и в контролера ще работи правилно.

1
23/03/2017 11:35:03
ibosev avatar ibosev 54 Точки

За да не отварям нова тема, ще пиша тук.

След успешна регистрация или логин със Spring Social Facebook, с thymeleaf вече не мога да достъпя всички полета на юзъра чрез: 

#authentication.getPrincipal().{име на полето}

Предполагам, че е заради начина за логин, където ръчно сетваме autherntication token и го подаваме на SecurityContextHolder-a. Само предположения, но спря да работи както се очаква. 

private void loginUser(SocialUser socialUser) {
        Authentication authentication = new UsernamePasswordAuthenticationToken(socialUser.getUsername(), null, socialUser.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(authentication);
    }

 

EDIT: "Дебъгнах" какво пази #authentication.getPrincipal(), като просто го сложих в th:text в хедъра и се оказва, че в случая с BasicUser се принтира адреса в паметта на обекта и името на класа, докато при логин с ФБ (горния метод loginUser(SocialUser socialUser)), се изписва само username-а като чист String. Реших, че проблема е от вида на аутентикацията, потърсих друга, която да не е UsernamePasswordAuthenticationToken, но не намерих с един анонимен клас си реших въпроса:

Authentication authentication1 = new Authentication() {
            @Override
            public Collection<? extends GrantedAuthority> getAuthorities() {
                return socialUser.getAuthorities();
            }

            @Override
            public Object getCredentials() {
                return null;
            }

            @Override
            public Object getDetails() {
                return null;
            }

            @Override
            public Object getPrincipal() {
                return socialUser;
            }

            @Override
            public boolean isAuthenticated() {
                return true;
            }

            @Override
            public void setAuthenticated(boolean b) throws IllegalArgumentException {

            }

            @Override
            public String getName() {
                return socialUser.getUsername();
            }
        };

Много е грозно и силно ме съмнява това да е правилния начин, та ако може някой да даде съвет.

0
01/04/2017 17:29:55
vancho avatar vancho 429 Точки

Не става ли така? Примерно да ти даде logout само ако си се логнал.

<div sec:authorize="hasAnyRole('ADMIN', 'CHEMIST', 'MEDIC')" class="collapse navbar-collapse" id="navbarSupportedContent">
    <ul class="navbar-nav mr-auto">
        <li class="nav-item">
            <a class="nav-link" th:href="@{/logout}">logout</a>
        </li>
    </ul>
</div>
0
22/03/2017 21:08:09
ibosev avatar ibosev 54 Точки

Явно не съм успял да обясня както трябва. Това, което си показал е при дадена роля дали да се показва някакъв хтмл елемент или не.

Искам в хедъра да сложа информация, която я има в User entity-то. Примерно fullName полето. Най-елементарното е да го сложа в Session-а. Може и в Cookie. И оттам да си го дам на navbar-а. Трябва да има нещо много елементарно като решение, но не го знам :)

0