Security konfiguriert.

master
Markus Kreth 2 years ago
parent d9333851cf
commit 406331d33e
  1. 6
      pom.xml
  2. 8
      src/main/java/de/kreth/invoice/config/KeycloakConfigResolverLocal.java
  3. 4
      src/main/java/de/kreth/invoice/config/SecurityUtils.java
  4. 98
      src/main/java/de/kreth/invoice/config/UiSecurityConfig.java
  5. 2
      src/main/java/de/kreth/invoice/views/View.java
  6. 304
      src/main/java/de/kreth/invoice/views/user/UserDetailsDialog.java

@ -116,7 +116,6 @@
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<!-- <version>4.0.1</version> -->
<scope>provided</scope>
</dependency>
@ -163,6 +162,11 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-testbench</artifactId>

@ -8,9 +8,9 @@ import org.springframework.context.annotation.Configuration;
@Configuration
public class KeycloakConfigResolverLocal {
@Bean
public KeycloakConfigResolver keyCloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
@Bean
public KeycloakConfigResolver keyCloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
}

@ -11,6 +11,10 @@ import org.springframework.security.core.context.SecurityContextHolder;
import com.vaadin.flow.shared.ApplicationConstants;
public class SecurityUtils {
private SecurityUtils() {
}
/**
* Tests if the request is an internal framework request. The test consists of
* checking if the request parameter is present and if its value is consistent

@ -22,60 +22,58 @@ import org.springframework.security.web.authentication.session.SessionAuthentica
@KeycloakConfiguration
public class UiSecurityConfig extends KeycloakWebSecurityConfigurerAdapter {
@Autowired
private KeycloakClientRequestFactory factory;
@Autowired
private KeycloakClientRequestFactory factory;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
KeycloakAuthenticationProvider keyCloakAuthProvider = keycloakAuthenticationProvider();
keyCloakAuthProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
auth.authenticationProvider(keyCloakAuthProvider);
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
KeycloakAuthenticationProvider keyCloakAuthProvider = keycloakAuthenticationProvider();
keyCloakAuthProvider.setGrantedAuthoritiesMapper(new SimpleAuthorityMapper());
auth.authenticationProvider(keyCloakAuthProvider);
}
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public KeycloakRestTemplate restTemplate() {
return new KeycloakRestTemplate(factory);
}
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public KeycloakRestTemplate restTemplate() {
return new KeycloakRestTemplate(factory);
}
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}
@Bean
@Override
protected SessionAuthenticationStrategy sessionAuthenticationStrategy() {
return new RegisterSessionAuthenticationStrategy(new SessionRegistryImpl());
}
@Override
public void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.cors().disable()
.csrf().disable()
.anonymous().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED).and()
.authorizeRequests().requestMatchers(SecurityUtils::isFrameworkInternalRequest).permitAll()
.anyRequest().hasAnyRole("ROLE_trainer", "ROLE_admin");
}
@Override
public void configure(HttpSecurity http) throws Exception {
super.configure(http);
http.cors().disable().csrf().disable().anonymous().disable().sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED).and().authorizeRequests()
.requestMatchers(SecurityUtils::isFrameworkInternalRequest).permitAll().anyRequest()
.hasAnyRole("admin", "INVOICE_USER");
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers(
// Vaadin Flow static resources //
"/VAADIN/**",
// the standard favicon URI
"/favicon.ico",
// the robots exclusion standard
"/robots.txt",
// web application manifest //
"/manifest.webmanifest", "/sw.js", "/offline-page.html",
// (development mode) static resources //
"/frontend/**",
// (development mode) webjars //
"/webjars/**",
// (production mode) static resources //
"/frontend-es5/**", "/frontend-es6/**");
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers(
// Vaadin Flow static resources //
"/VAADIN/**",
// the standard favicon URI
"/favicon.ico",
// the robots exclusion standard
"/robots.txt",
// web application manifest //
"/manifest.webmanifest", "/sw.js", "/offline-page.html",
// (development mode) static resources //
"/frontend/**",
// (development mode) webjars //
"/webjars/**",
// (production mode) static resources //
"/frontend-es5/**", "/frontend-es6/**");
}
@Bean
public static KeycloakConfigResolver keycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
@Bean
public static KeycloakConfigResolver keycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
}

@ -5,7 +5,6 @@ import java.util.Iterator;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import com.vaadin.flow.component.ClickEvent;
import com.vaadin.flow.component.Text;
@ -42,7 +41,6 @@ import de.kreth.invoice.views.user.UserDetailsDialog;
@PageTitle("")
@Route(value = "")
@PreAuthorize("hasRole('INVOICE_USER')")
public class View extends VerticalLayout implements BeforeEnterObserver {
private static final long serialVersionUID = 1L;

@ -33,44 +33,44 @@ import de.kreth.invoice.report.Signature;
public class UserDetailsDialog extends Dialog {
private static final long serialVersionUID = -6255487997073609068L;
private static final long serialVersionUID = -6255487997073609068L;
private Logger logger = LoggerFactory.getLogger(getClass());
private Logger logger = LoggerFactory.getLogger(getClass());
private final Binder<UserBank> bankBinder = new Binder<>();
private final Binder<UserAdress> adressBinder = new Binder<>();
private final Binder<UserBank> bankBinder = new Binder<>();
private final Binder<UserAdress> adressBinder = new Binder<>();
// private final TextField loginName;
private final TextField prename;
private final TextField prename;
private final TextField surname;
private final TextField surname;
private final TextField bankName;
private final TextField bankName;
private final TextField iban;
private final TextField iban;
private final TextField bic;
private final TextField bic;
private final TextField adress1;
private final TextField adress1;
private final TextField adress2;
private final TextField adress2;
private final TextField zipCode;
private final TextField zipCode;
private final TextField city;
private final TextField city;
private final Button okButton;
private final Button okButton;
private final Image signatureImage;
private final Upload upload;
private final Image signatureImage;
private final Upload upload;
private User user;
private User user;
private boolean isValidAndClosedWithOk = false;
private boolean isValidAndClosedWithOk = false;
public UserDetailsDialog(// UserBankRepository bankRepository, UserAdressRepository adressRepository
) {
public UserDetailsDialog(// UserBankRepository bankRepository, UserAdressRepository adressRepository
) {
// this.bankRepository = bankRepository;
// this.adressRepository = adressRepository;
@ -78,151 +78,145 @@ public class UserDetailsDialog extends Dialog {
// loginName.setLabel("Login Name");
// loginName.setEnabled(false);
prename = new TextField();
prename.setLabel("Vorname");
prename.setEnabled(false);
surname = new TextField();
surname.setLabel("Nachname");
surname.setEnabled(false);
bankName = new TextField();
bankName.setLabel("Name der Bank");
bankBinder.forField(bankName)
.asRequired("Der BankName darf nicht leer sein.")
.bind(UserBank::getBankName, UserBank::setBankName);
iban = new TextField();
iban.setLabel("IBAN");
bankBinder.forField(iban)
.asRequired("Die IBAN darf nicht leer sein.")
.bind(UserBank::getIban, UserBank::setIban);
bic = new TextField();
bic.setLabel("BIC");
bankBinder.forField(bic).bind(UserBank::getBic, UserBank::setBic);
adress1 = new TextField();
adress1.setLabel("Straße");
adressBinder.forField(adress1)
.asRequired("Die Straße muss angegeben sein.")
.bind(UserAdress::getAdress1, UserAdress::setAdress1);
adress2 = new TextField();
adress2.setLabel("Adresszusatz");
adressBinder.forField(adress2)
.bind(UserAdress::getAdress2, UserAdress::setAdress2);
zipCode = new TextField();
zipCode.setLabel("Postleitzahl");
adressBinder.forField(zipCode)
.asRequired("Die Postleitzahl muss angegeben sein.")
.bind(UserAdress::getZip, UserAdress::setZip);
city = new TextField();
city.setLabel("Ort");
adressBinder.forField(city)
.asRequired("Der Ort muss angegeben sein.")
.bind(UserAdress::getCity, UserAdress::setCity);
signatureImage = new Image();
signatureImage.setAlt("Keine Unterschrift konfiguriert");
upload = new Upload(this::receiveUpload);
upload.addFinishedListener(ev -> updateSignatureImage());
VerticalLayout layout = new VerticalLayout();
layout.add(prename, surname);
layout.add(new Hr());
layout.add(bankName, iban, bic);
layout.add(new Hr());
HorizontalLayout cityLayout = new HorizontalLayout();
cityLayout.add(zipCode, city);
layout.add(adress1, adress2, cityLayout, new FormLayout(signatureImage, upload));
okButton = new Button("OK", ev -> {
BinderValidationStatus<UserBank> bankValidation = bankBinder.validate();
BinderValidationStatus<UserAdress> adressValidation = adressBinder.validate();
if (bankValidation.isOk() && adressValidation.isOk()) {
user.setBank(bankBinder.getBean());
user.setAdress(adressBinder.getBean());
isValidAndClosedWithOk = true;
close();
}
});
Button cancel = new Button("Abbrechen", ev -> close());
HorizontalLayout buttons = new HorizontalLayout();
buttons.add(okButton, cancel);
layout.add(buttons);
add(layout);
}
private OutputStream receiveUpload(String filename, String mimeType) {
Signature signature = new Signature(user);
try {
return signature.createOutputStream(filename);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
prename = new TextField();
prename.setLabel("Vorname");
prename.setEnabled(false);
surname = new TextField();
surname.setLabel("Nachname");
surname.setEnabled(false);
bankName = new TextField();
bankName.setLabel("Name der Bank");
bankBinder.forField(bankName).asRequired("Der BankName darf nicht leer sein.").bind(UserBank::getBankName,
UserBank::setBankName);
iban = new TextField();
iban.setLabel("IBAN");
bankBinder.forField(iban).asRequired("Die IBAN darf nicht leer sein.").bind(UserBank::getIban,
UserBank::setIban);
bic = new TextField();
bic.setLabel("BIC");
bankBinder.forField(bic).bind(UserBank::getBic, UserBank::setBic);
adress1 = new TextField();
adress1.setLabel("Straße");
adressBinder.forField(adress1).asRequired("Die Straße muss angegeben sein.").bind(UserAdress::getAdress1,
UserAdress::setAdress1);
adress2 = new TextField();
adress2.setLabel("Adresszusatz");
adressBinder.forField(adress2).bind(UserAdress::getAdress2, UserAdress::setAdress2);
zipCode = new TextField();
zipCode.setLabel("Postleitzahl");
adressBinder.forField(zipCode).asRequired("Die Postleitzahl muss angegeben sein.").bind(UserAdress::getZip,
UserAdress::setZip);
city = new TextField();
city.setLabel("Ort");
adressBinder.forField(city).asRequired("Der Ort muss angegeben sein.").bind(UserAdress::getCity,
UserAdress::setCity);
signatureImage = new Image();
signatureImage.setAlt("Keine Unterschrift konfiguriert");
upload = new Upload(this::receiveUpload);
upload.addFinishedListener(ev -> updateSignatureImage());
VerticalLayout layout = new VerticalLayout();
layout.add(prename, surname);
layout.add(new Hr());
layout.add(bankName, iban, bic);
layout.add(new Hr());
HorizontalLayout cityLayout = new HorizontalLayout();
cityLayout.add(zipCode, city);
layout.add(adress1, adress2, cityLayout, new FormLayout(signatureImage, upload));
okButton = new Button("OK", ev -> {
BinderValidationStatus<UserBank> bankValidation = bankBinder.validate();
BinderValidationStatus<UserAdress> adressValidation = adressBinder.validate();
if (bankValidation.isOk() && adressValidation.isOk()) {
user.setBank(bankBinder.getBean());
user.setAdress(adressBinder.getBean());
isValidAndClosedWithOk = true;
close();
}
});
public void setUser(User user) {
Button cancel = new Button("Abbrechen", ev -> close());
this.user = Objects.requireNonNull(user);
HorizontalLayout buttons = new HorizontalLayout();
buttons.add(okButton, cancel);
layout.add(buttons);
this.prename.setValue(user.getGivenName());
this.surname.setValue(user.getFamilyName());
bankBinder.setBean(user.getBank().clone());
adressBinder.setBean(user.getAdress().clone());
updateSignatureImage();
}
add(layout);
}
public boolean isValidAndClosedWithOk() {
return isValidAndClosedWithOk;
}
private OutputStream receiveUpload(String filename, String mimeType) {
private void updateSignatureImage() {
if (user != null && user.getId() != null) {
upload.setUploadButton(null);
Signature signature = new Signature(user);
if (signature.isSignatureImageExists()) {
File signatureUrl = signature.getSignatureUrl();
logger.info("Showing signature: {}", signatureUrl);
Signature signature = new Signature(user);
try {
return signature.createOutputStream(filename);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
StreamResource resource = new StreamResource("Unterschrift", new InputStreamFactory() {
public void setUser(User user) {
private static final long serialVersionUID = 1L;
this.user = Objects.requireNonNull(user);
@Override
public InputStream createInputStream() {
try {
return new FileInputStream(signatureUrl);
} catch (FileNotFoundException e) {
throw new UncheckedIOException(e);
this.prename.setValue(user.getGivenName());
this.surname.setValue(user.getFamilyName());
bankBinder.setBean(user.getBank().clone());
adressBinder.setBean(user.getAdress().clone());
updateSignatureImage();
}
public boolean isValidAndClosedWithOk() {
return isValidAndClosedWithOk;
}
private void updateSignatureImage() {
if (user != null && user.getId() != null) {
upload.setUploadButton(null);
Signature signature = new Signature(user);
if (signature.isSignatureImageExists()) {
File signatureUrl = signature.getSignatureUrl();
logger.info("Showing signature: {}", signatureUrl);
StreamResource resource = new StreamResource("Unterschrift", new InputStreamFactory() {
private static final long serialVersionUID = 1L;
@Override
public InputStream createInputStream() {
try {
return new FileInputStream(signatureUrl);
} catch (FileNotFoundException e) {
throw new UncheckedIOException(e);
}
}
});
signatureImage.setWidth("192px");
signatureImage.setHeight("62px");
signatureImage.setSrc(resource);
}
}
});
signatureImage.setWidth("192px");
signatureImage.setHeight("62px");
signatureImage.setSrc(resource);
}
} else {
signatureImage.setWidth(null);
signatureImage.setHeight(null);
upload.setVisible(false);
signatureImage.setAlt(
"Eine Unterschrift kann konfiguriert werden, nachdem die Benutzerdaten gespeichert wurden.");
} else {
signatureImage.setWidth(null);
signatureImage.setHeight(null);
upload.setVisible(false);
signatureImage.setAlt(
"Eine Unterschrift kann konfiguriert werden, nachdem die Benutzerdaten gespeichert wurden.");
}
}
}
public User getUser() {
return user;
}
public User getUser() {
return user;
}
}

Loading…
Cancel
Save