Reputation: 67
I have a fragment for my web application which is used across multiple pages to display a navbar with the user logged in : if they are logged in, if not : display login & signup button.
I want to know how to include my attribute of a logged in user to a fragment as currently I have the logged in user attribute mapped to each controller displaying a web page, not a fragment.
To get the current logged in user I use
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
model.addAttribute("loggedinuser", authentication.getName());
However this is only specific to one get request. I want to be able to display the logged in user in a fragment which is then called by each page.
Here is an example of a controller getting the logged in user
@GetMapping(path= "")
public String getMainPage(HttpServletRequest request, Model model) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
model.addAttribute("loggedinuser", authentication.getName());
model.addAttribute("roles", authentication.getAuthorities());
return "mainpage";
}
Here is my class extending WebSecurityConfigurerAdapter to authenticate a users username and password against one in the database
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
String userbyUsernameQuery = "select username, password, '1' as enabled from auth_user where username=?;";
String rolebyUsernameQuery = "SELECT auth_user.username, auth_role.role_name as authority from auth_user\n" +
"INNER JOIN auth_user_role ON auth_user.auth_user_id = auth_user_role.auth_user_id\n" +
"INNER JOIN auth_role ON auth_role.auth_role_id = auth_user_role.auth_role_id\n" +
"WHERE auth_user.username =?";
auth.jdbcAuthentication()
.dataSource(dataSource)
.usersByUsernameQuery(userbyUsernameQuery)
.authoritiesByUsernameQuery(rolebyUsernameQuery)
.passwordEncoder(passwordEncoder());
}
The part of the navbarHeader fragment I want to change is this
<ul class="nav navbar-nav navbar-right">
<li><a th:href="@{/registration}"><span class="glyphicon glyphicon-user"></span>Sign up</a></li>
<li><a th:href="@{/login}"><span class="glyphicon glyphicon-log-in"></span> Login</a></li>
</ul>
I want to display the logged in user if logged in & disable the sign up button. If not then display the log in button & signup button
Here is my mainpage page which displays the current user logged in and role which I want to move to the fragment so I do not need to add all the code in each controller & html page.
<div align="right" id="loggedIn" th:if="${loggedinuser != null}">
<div style="margin: 10px"
th:text="'Logged in as: '+${loggedinuser} + ' Role: ' +${roles}">
</div>
</div>
The user class
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User{
private int id;
private String name;
private String lastName;
private String username;
private String password;
private String email;
private String enabled;
public User(String name, Collection<? extends GrantedAuthority> authorities) {
}
}
Upvotes: 1
Views: 2032
Reputation: 2052
For this issue I basically utilize ModelAttribute
which would be available across all the Presentation compilation. So your controller would like this
public class MyController {
@GetMapping(path= "hi")
public String getMainPage(HttpServletRequest request, Model model) {
return "mainpage";
}
@GetMapping(path= "hello")
public String getMainPage(HttpServletRequest request, Model model) {
return "helloPage";
}
@ModelAttribute("loggedinuser")
public User globalUserObject() {
// Add all null check and authentication check before using. Because this is global
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
model.addAttribute("loggedinuser", authentication.getName());
model.addAttribute("roles", authentication.getAuthorities());
// Create User pojo class
User user = new User(authentication.getName(), Arrays.asList(authentication.getAuthorities()))
return user;
}
}
Now the object loggedinuser
available for all the pages.
Upvotes: 1