Added bootstrap and proper authentication

This commit is contained in:
Andrew Lalis 2019-05-13 22:08:45 +02:00 committed by andrewlalis
parent b02b3faa57
commit b1b5f11f18
12 changed files with 152 additions and 26 deletions

View File

@ -3,6 +3,7 @@ package nl.andrewlalis.teaching_assistant_assistant;
import org.springframework.boot.CommandLineRunner; import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@SpringBootApplication @SpringBootApplication
public class TeachingAssistantAssistantApplication implements CommandLineRunner { public class TeachingAssistantAssistantApplication implements CommandLineRunner {
@ -14,5 +15,6 @@ public class TeachingAssistantAssistantApplication implements CommandLineRunner
@Override @Override
public void run(String... args) throws Exception { public void run(String... args) throws Exception {
System.out.println("Running startup..."); System.out.println("Running startup...");
System.out.println(new BCryptPasswordEncoder().encode("test"));
} }
} }

View File

@ -22,10 +22,6 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override @Override
protected void configure(final AuthenticationManagerBuilder auth) throws Exception { protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("tester")
.password(passwordEncoder().encode("tester"))
.roles("USER");
auth.userDetailsService(this.userDetailsService); auth.userDetailsService(this.userDetailsService);
} }
@ -35,25 +31,31 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
.csrf().disable() // So that we can GET the logout page. .csrf().disable() // So that we can GET the logout page.
.authorizeRequests() // Let anyone view the login and logout pages. .authorizeRequests() // Let anyone view the login and logout pages.
.antMatchers("/login*", "/logout*") .antMatchers("/login*", "/logout*", "/register*")
.permitAll()
.and()
.authorizeRequests()
.antMatchers("/css/**")
.permitAll() .permitAll()
.anyRequest()
.authenticated()
.and() .and()
.authorizeRequests() // Only logged in users should be able to see site content. .authorizeRequests() // Only logged in users should be able to see site content.
.antMatchers("/**") .antMatchers("/**")
.hasRole("USER") .hasRole("USER")
.anyRequest().authenticated()
.and() .and()
.formLogin() .formLogin()
.loginPage("/login") .loginPage("/login")
.permitAll()
.loginProcessingUrl("/login") .loginProcessingUrl("/login")
.defaultSuccessUrl("/", true) .defaultSuccessUrl("/", true)
.failureUrl("/login?error") .failureUrl("/login?error")
.and() .and()
.logout() .logout()
.permitAll()
.clearAuthentication(true) .clearAuthentication(true)
.invalidateHttpSession(true) .invalidateHttpSession(true)
.logoutUrl("/logout") .logoutUrl("/logout")

View File

@ -1,5 +1,7 @@
package nl.andrewlalis.teaching_assistant_assistant.controllers; package nl.andrewlalis.teaching_assistant_assistant.controllers;
import nl.andrewlalis.teaching_assistant_assistant.model.security.UserDetails;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
@ -11,9 +13,10 @@ public class RootController {
path = "/", path = "/",
produces = "text/html" produces = "text/html"
) )
public String index(Model model) { public String index(Authentication authentication, Model model) {
model.addAttribute("name", "JOHN"); UserDetails userDetails = (UserDetails) authentication.getPrincipal();
return "index.html"; model.addAttribute("user", userDetails.getUser());
return "index";
} }
} }

View File

@ -3,6 +3,7 @@ package nl.andrewlalis.teaching_assistant_assistant.model.people;
import nl.andrewlalis.teaching_assistant_assistant.model.BasicEntity; import nl.andrewlalis.teaching_assistant_assistant.model.BasicEntity;
import nl.andrewlalis.teaching_assistant_assistant.model.Course; import nl.andrewlalis.teaching_assistant_assistant.model.Course;
import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.Team; import nl.andrewlalis.teaching_assistant_assistant.model.people.teams.Team;
import nl.andrewlalis.teaching_assistant_assistant.model.security.User;
import javax.persistence.*; import javax.persistence.*;
import java.util.ArrayList; import java.util.ArrayList;
@ -68,6 +69,16 @@ public abstract class Person extends BasicEntity {
) )
private List<Course> courses; private List<Course> courses;
/**
* The authenticated user belonging to this person.
*/
@OneToOne(
fetch = FetchType.LAZY,
optional = true,
mappedBy = "person"
)
private User user;
/** /**
* Default constructor for JPA. * Default constructor for JPA.
*/ */
@ -167,6 +178,14 @@ public abstract class Person extends BasicEntity {
return this.teams; return this.teams;
} }
public User getUser() {
return this.user;
}
public void setUser(User user) {
this.user = user;
}
/** /**
* Determines if two Persons are equal. They are considered equal when all of the basic identifying information * Determines if two Persons are equal. They are considered equal when all of the basic identifying information
* about the person is the same, regardless of case. * about the person is the same, regardless of case.

View File

@ -20,11 +20,18 @@ public class User extends BasicEntity {
@Column(nullable = false, unique = true) @Column(nullable = false, unique = true)
private String username; private String username;
/**
* The password for this user.
*/
@Column @Column
private String password; private String password;
@OneToOne @OneToOne
@JoinColumn(name = "person_id", nullable = true, referencedColumnName = "id") @JoinColumn(
name = "person_id",
nullable = true,
referencedColumnName = "id"
)
private Person person; private Person person;
public String getUsername() { public String getUsername() {

View File

@ -1,20 +1,26 @@
package nl.andrewlalis.teaching_assistant_assistant.model.security; package nl.andrewlalis.teaching_assistant_assistant.model.security;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
public class UserDetails implements org.springframework.security.core.userdetails.UserDetails { public class UserDetails implements org.springframework.security.core.userdetails.UserDetails {
private User user; private User user;
public UserDetails(User user) { protected UserDetails(User user) {
this.user = user; this.user = user;
} }
public User getUser() {
return this.user;
}
@Override @Override
public Collection<? extends GrantedAuthority> getAuthorities() { public Collection<? extends GrantedAuthority> getAuthorities() {
return null; return Collections.singleton(new SimpleGrantedAuthority("ROLE_USER"));
} }
@Override @Override

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,35 @@
body {
text-align: center;
}
.page_row {
text-align: center;
}
.login_form {
background-color: green;
color: white;
width: 50%;
text-align: center;
margin-left: auto;
margin-right: auto;
padding: 10px;
}
.login_form_row {
width: 100%;
margin-top: 10px;
margin-bottom: 10px;
}
.login_form label {
font-size: 18px;
}
.login_form input {
font-family: inherit;
}
.login_form input[type=submit]:hover {
background-color: lightgray;
}

View File

@ -1,6 +1,7 @@
/* Set the font for the whole website here. */ /* Set the font for the whole website here. */
body { body {
font-family: sans-serif; font-family: sans-serif;
background-color: white;
} }
.content_container { .content_container {
@ -32,6 +33,11 @@ body {
color: inherit; color: inherit;
} }
.white_link {
text-decoration: underline;
color: white;
}
.sidebar_block a:hover { .sidebar_block a:hover {
color: lightgreen; color: lightgreen;
} }

View File

@ -9,7 +9,7 @@
<nav th:fragment="header" class="header_bar"> <nav th:fragment="header" class="header_bar">
<link rel="stylesheet" href="../../../resources/static/css/header.css" th:href="@{/css/header.css}"/> <link rel="stylesheet" href="../../../resources/static/css/header.css" th:href="@{/css/header.css}"/>
<h1 class="header_title">Teaching Assistant Assistant</h1> <h1 class="header_title">Teaching Assistant <em>Assistant</em></h1>
<ul class="header_link_list"> <ul class="header_link_list">
<li><a href="/" th:href="@{/}">Home</a> <li><a href="/" th:href="@{/}">Home</a>
<li><a href="/courses" th:href="@{/courses}">Courses</a> <li><a href="/courses" th:href="@{/courses}">Courses</a>

View File

@ -10,7 +10,7 @@
<hr> <hr>
<p> <p>
Welcome to the Teaching Assistant Assistant. To find the courses in this application please follow the link to Welcome to the Teaching Assistant Assistant, <span th:text="${user.getPerson().getFullName()}"></span>. To find the courses in this application please follow the link to
<a th:href="@{/courses}">courses</a>. <a th:href="@{/courses}">courses</a>.
</p> </p>

View File

@ -3,22 +3,61 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Login</title> <title>Login</title>
<link rel="stylesheet" th:href="@{/css/style.css}" type="text/css"/>
<link rel="stylesheet" th:href="@{/css/login.css}" type="text/css"/>
</head> </head>
<body> <body>
<div th:if="${param.error}"> <div class="content_container">
Invalid username or password! <div class="page_row">
</div> <h1>Teaching Assistant <em>Assistant</em></h1>
</div>
<div th:if="${param.logout}"> <div class="page_row">
You have been logged out! <div th:if="${param.error}">
</div> Invalid username or password!
</div>
<form th:action="@{/login}" method="post"> <div th:if="${param.logout}">
<label>Username: <input type="text" name="username"/></label> You have been logged out!
<label>Password: <input type="password" name="password"/></label> </div>
<button type="submit">Login</button> </div>
</form>
<div class="page_row">
<h2>Login</h2>
<p>
Please log in to access this application.
</p>
</div>
<div class="page_row">
<form class="login_form" th:action="@{/login}" method="post">
<div class="login_form_row">
<label for="username_input">Username</label>
</div>
<div class="login_form_row">
<input id="username_input" type="text" name="username"/>
</div>
<div class="login_form_row">
<label for="password_input">Password</label>
</div>
<div class="login_form_row">
<input id="password_input" type="password" name="password"/>
</div>
<div class="login_form_row">
<input type="submit" value="Login"/>
</div>
<div class="login_form_row">
<a class="white_link" th:href="@{/register}">Don't have an account? Sign up here!</a>
</div>
</form>
</div>
</div>
</body> </body>
</html> </html>