Loading...
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 Trainer 46 Точки
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 Trainer 46 Точки

Точно така. И в 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 430 Точки

Не става ли така? Примерно да ти даде 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
sukalu88 avatar sukalu88 43 Точки

The article is easy to understand, detailed and meticulous! I had a lot of harvest after seeing this post from you! I found it interesting, your article gave me a new perspective! I have read many other articles on the same topic, but yours convinced me! fireboy and watergirl

0
goalken avatar goalken 5 Точки

I really like reading through a post that can make people think. Also, many thanks for permitting me to comment! basketball legends

0
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.