mirror of
https://github.com/TanelOrumaa/Estonian-ID-card-mobile-authenticator-POC.git
synced 2024-12-22 20:40:16 +02:00
MOB-55 Added session cookies reading
This commit is contained in:
parent
4096201bef
commit
7482c88a4e
46
demoBackend/src/demo-website/package-lock.json
generated
46
demoBackend/src/demo-website/package-lock.json
generated
@ -10,9 +10,10 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@web-eid/web-eid-library": "../../../../web-eid.js/",
|
"@web-eid/web-eid-library": "../../../../web-eid.js/",
|
||||||
"core-js": "^3.6.5",
|
"core-js": "^3.6.5",
|
||||||
"js-cookie": "^3.0.1",
|
|
||||||
"vue": "^3.0.0",
|
"vue": "^3.0.0",
|
||||||
|
"vue-cookie-next": "^1.3.0",
|
||||||
"vue-router": "^4.0.0-0",
|
"vue-router": "^4.0.0-0",
|
||||||
|
"vue3-cookies": "^1.0.6",
|
||||||
"vuex": "^4.0.2",
|
"vuex": "^4.0.2",
|
||||||
"vuex-persistedstate": "^4.1.0"
|
"vuex-persistedstate": "^4.1.0"
|
||||||
},
|
},
|
||||||
@ -8668,14 +8669,6 @@
|
|||||||
"integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==",
|
"integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/js-cookie": {
|
|
||||||
"version": "3.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.1.tgz",
|
|
||||||
"integrity": "sha512-+0rgsUXZu4ncpPxRL+lNEptWMOWl9etvPHc/koSRp6MPwpRYAhmk0dUG00J4bxVV3r9uUzfo24wW0knS07SKSw==",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/js-message": {
|
"node_modules/js-message": {
|
||||||
"version": "1.0.7",
|
"version": "1.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/js-message/-/js-message-1.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/js-message/-/js-message-1.0.7.tgz",
|
||||||
@ -13982,6 +13975,14 @@
|
|||||||
"@vue/shared": "3.2.23"
|
"@vue/shared": "3.2.23"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/vue-cookie-next": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/vue-cookie-next/-/vue-cookie-next-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-+EinbhSf0c0M8cijCXRVgcvYBIm0lmu3/WKeFUokU93R1J3DxkkBHn5wOc9IyJj9ugAPI0d9EnhcOiOFNA/YVQ==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"vue": "^3.1.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/vue-eslint-parser": {
|
"node_modules/vue-eslint-parser": {
|
||||||
"version": "7.11.0",
|
"version": "7.11.0",
|
||||||
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.11.0.tgz",
|
||||||
@ -14196,6 +14197,14 @@
|
|||||||
"integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
|
"integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/vue3-cookies": {
|
||||||
|
"version": "1.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/vue3-cookies/-/vue3-cookies-1.0.6.tgz",
|
||||||
|
"integrity": "sha512-a1UvVD0qIgxyOqjlSOwnLnqAnz8ASltugEv8yX+96i/WGZAN9fEDci7xO4HIWZE1uToUnRq9JnFhvfDCSo45OA==",
|
||||||
|
"dependencies": {
|
||||||
|
"vue": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/vuex": {
|
"node_modules/vuex": {
|
||||||
"version": "4.0.2",
|
"version": "4.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/vuex/-/vuex-4.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/vuex/-/vuex-4.0.2.tgz",
|
||||||
@ -21996,11 +22005,6 @@
|
|||||||
"integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==",
|
"integrity": "sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"js-cookie": {
|
|
||||||
"version": "3.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.1.tgz",
|
|
||||||
"integrity": "sha512-+0rgsUXZu4ncpPxRL+lNEptWMOWl9etvPHc/koSRp6MPwpRYAhmk0dUG00J4bxVV3r9uUzfo24wW0knS07SKSw=="
|
|
||||||
},
|
|
||||||
"js-message": {
|
"js-message": {
|
||||||
"version": "1.0.7",
|
"version": "1.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/js-message/-/js-message-1.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/js-message/-/js-message-1.0.7.tgz",
|
||||||
@ -26418,6 +26422,12 @@
|
|||||||
"@vue/shared": "3.2.23"
|
"@vue/shared": "3.2.23"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"vue-cookie-next": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/vue-cookie-next/-/vue-cookie-next-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-+EinbhSf0c0M8cijCXRVgcvYBIm0lmu3/WKeFUokU93R1J3DxkkBHn5wOc9IyJj9ugAPI0d9EnhcOiOFNA/YVQ==",
|
||||||
|
"requires": {}
|
||||||
|
},
|
||||||
"vue-eslint-parser": {
|
"vue-eslint-parser": {
|
||||||
"version": "7.11.0",
|
"version": "7.11.0",
|
||||||
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.11.0.tgz",
|
||||||
@ -26585,6 +26595,14 @@
|
|||||||
"integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
|
"integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"vue3-cookies": {
|
||||||
|
"version": "1.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/vue3-cookies/-/vue3-cookies-1.0.6.tgz",
|
||||||
|
"integrity": "sha512-a1UvVD0qIgxyOqjlSOwnLnqAnz8ASltugEv8yX+96i/WGZAN9fEDci7xO4HIWZE1uToUnRq9JnFhvfDCSo45OA==",
|
||||||
|
"requires": {
|
||||||
|
"vue": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"vuex": {
|
"vuex": {
|
||||||
"version": "4.0.2",
|
"version": "4.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/vuex/-/vuex-4.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/vuex/-/vuex-4.0.2.tgz",
|
||||||
|
@ -10,9 +10,10 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@web-eid/web-eid-library": "../../../../web-eid.js/",
|
"@web-eid/web-eid-library": "../../../../web-eid.js/",
|
||||||
"core-js": "^3.6.5",
|
"core-js": "^3.6.5",
|
||||||
"js-cookie": "^3.0.1",
|
|
||||||
"vue": "^3.0.0",
|
"vue": "^3.0.0",
|
||||||
|
"vue-cookie-next": "^1.3.0",
|
||||||
"vue-router": "^4.0.0-0",
|
"vue-router": "^4.0.0-0",
|
||||||
|
"vue3-cookies": "^1.0.6",
|
||||||
"vuex": "^4.0.2",
|
"vuex": "^4.0.2",
|
||||||
"vuex-persistedstate": "^4.1.0"
|
"vuex-persistedstate": "^4.1.0"
|
||||||
},
|
},
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
<p class="text-center">Read more from <a href="https://github.com/TanelOrumaa/Estonian-ID-card-mobile-authenticator-POC">here.</a></p>
|
<p class="text-center">Read more from <a href="https://github.com/TanelOrumaa/Estonian-ID-card-mobile-authenticator-POC">here.</a></p>
|
||||||
</div>
|
</div>
|
||||||
<div class="justify-content-center d-flex">
|
<div class="justify-content-center d-flex">
|
||||||
|
<div id="canvas"></div>
|
||||||
<button type="button" class="btn loginButton btn-dark" v-on:click="authenticate">
|
<button type="button" class="btn loginButton btn-dark" v-on:click="authenticate">
|
||||||
<div v-if="loading" class="d-flex justify-content-center">
|
<div v-if="loading" class="d-flex justify-content-center">
|
||||||
<div class="spinner-border text-light spinner-border-sm" role="status">
|
<div class="spinner-border text-light spinner-border-sm" role="status">
|
||||||
@ -26,7 +26,7 @@
|
|||||||
<input type="radio" class="btn-check" name="btnradio" id="btnApp" autocomplete="off" checked v-on:click="useApp">
|
<input type="radio" class="btn-check" name="btnradio" id="btnApp" autocomplete="off" checked v-on:click="useApp">
|
||||||
<label class="btn btn-outline-secondary" for="btnApp">using Android App</label>
|
<label class="btn btn-outline-secondary" for="btnApp">using Android App</label>
|
||||||
</div>
|
</div>
|
||||||
<div id="canvas"></div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
@ -66,7 +66,7 @@ export default {
|
|||||||
getAuthSuccessUrl: window.location.origin + "/auth/login",
|
getAuthSuccessUrl: window.location.origin + "/auth/login",
|
||||||
useAuthApp: this.useAndroidApp,
|
useAuthApp: this.useAndroidApp,
|
||||||
headers: {
|
headers: {
|
||||||
[this.csrfHeaderName]: this.csrftoken
|
"sessionId": this.$store.getters.getSessionId
|
||||||
},
|
},
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -90,7 +90,7 @@ export default {
|
|||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
isLoggedIn() {
|
isLoggedIn() {
|
||||||
return this.$store.authenticated;
|
return this.$store.getAuthenticated;
|
||||||
},
|
},
|
||||||
loading() {
|
loading() {
|
||||||
return this.loading;
|
return this.loading;
|
||||||
@ -112,6 +112,10 @@ export default {
|
|||||||
.loginButton > p {
|
.loginButton > p {
|
||||||
font-size: 3vh;
|
font-size: 3vh;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#canvas {
|
||||||
|
height: 5vh;
|
||||||
|
width: 5vh;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -25,6 +25,12 @@ export default {
|
|||||||
this.$store.commit("setLoggedIn", false);
|
this.$store.commit("setLoggedIn", false);
|
||||||
router.push("/");
|
router.push("/");
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
if (this.$store.getters.getSessionId == null) {
|
||||||
|
const sessionId = this.$cookie.getCookie("JSESSIONID");
|
||||||
|
this.$store.dispatch("fetchSessionId", sessionId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
import {createApp} from 'vue';
|
import {createApp} from 'vue';
|
||||||
import App from './App.vue';
|
import App from './App.vue';
|
||||||
import {createStore} from 'vuex'
|
import {createStore} from 'vuex';
|
||||||
import BootstrapVue3 from 'bootstrap-vue-3'
|
import BootstrapVue3 from 'bootstrap-vue-3';
|
||||||
import createPersistedState from "vuex-persistedstate";
|
import createPersistedState from "vuex-persistedstate";
|
||||||
|
import { VueCookieNext } from 'vue-cookie-next'
|
||||||
|
|
||||||
|
|
||||||
import 'bootstrap/dist/css/bootstrap.css'
|
import 'bootstrap/dist/css/bootstrap.css'
|
||||||
import 'bootstrap-vue-3/dist/bootstrap-vue-3.css'
|
import 'bootstrap-vue-3/dist/bootstrap-vue-3.css'
|
||||||
@ -13,17 +15,28 @@ const store = createStore({
|
|||||||
state() {
|
state() {
|
||||||
return {
|
return {
|
||||||
authenticated: false,
|
authenticated: false,
|
||||||
|
jSessionId: null,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mutations: {
|
mutations: {
|
||||||
setLoggedIn(state, isLoggedIn) {
|
setLoggedIn(state, isLoggedIn) {
|
||||||
console.log("Setting logged in: " + isLoggedIn);
|
|
||||||
state.authenticated = isLoggedIn;
|
state.authenticated = isLoggedIn;
|
||||||
|
},
|
||||||
|
setSessionId(state, sessionId) {
|
||||||
|
state.jSessionId = sessionId;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
fetchSessionId(context, sessionId) {
|
||||||
|
context.commit("setSessionId", sessionId);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getters: {
|
getters: {
|
||||||
getAuthenticated: state => {
|
getAuthenticated: state => {
|
||||||
return state.authenticated;
|
return state.authenticated;
|
||||||
|
},
|
||||||
|
getSessionId: state => {
|
||||||
|
return state.jSessionId;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
plugins: [createPersistedState()],
|
plugins: [createPersistedState()],
|
||||||
@ -47,4 +60,7 @@ const app = createApp(App)
|
|||||||
app.use(BootstrapVue3)
|
app.use(BootstrapVue3)
|
||||||
app.use(router)
|
app.use(router)
|
||||||
app.use(store)
|
app.use(store)
|
||||||
|
app.use(VueCookieNext);
|
||||||
app.mount('#app')
|
app.mount('#app')
|
||||||
|
|
||||||
|
VueCookieNext.config({ expire: '7d' })
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
package com.tarkvaratehnika.demobackend.security
|
package com.tarkvaratehnika.demobackend.security
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty
|
class AuthTokenDTO (val token : String, val xsrfToken : String) {
|
||||||
|
|
||||||
class AuthTokenDTO (val token : String, val challenge : String) {
|
|
||||||
}
|
}
|
@ -54,13 +54,13 @@ object AuthTokenDTOAuthenticationProvider {
|
|||||||
fun authenticate(auth : Authentication) : Authentication {
|
fun authenticate(auth : Authentication) : Authentication {
|
||||||
val authentication = auth as PreAuthenticatedAuthenticationToken
|
val authentication = auth as PreAuthenticatedAuthenticationToken
|
||||||
val token = (authentication.credentials as AuthTokenDTO).token
|
val token = (authentication.credentials as AuthTokenDTO).token
|
||||||
val challenge = (authentication.credentials as AuthTokenDTO).challenge
|
val challenge = (authentication.credentials as AuthTokenDTO)
|
||||||
val authorities = arrayListOf<GrantedAuthority>()
|
val authorities = arrayListOf<GrantedAuthority>()
|
||||||
authorities.add(USER_ROLE)
|
authorities.add(USER_ROLE)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val userCertificate: X509Certificate = tokenValidator.validate(token)
|
val userCertificate: X509Certificate = tokenValidator.validate(token)
|
||||||
return WebEidAuthentication.fromCertificate(userCertificate, authorities, challenge)
|
return WebEidAuthentication.fromCertificate(userCertificate, authorities, "as")
|
||||||
} catch (e : TokenValidationException) {
|
} catch (e : TokenValidationException) {
|
||||||
// Validation failed.
|
// Validation failed.
|
||||||
throw AuthenticationServiceException("Token validation failed. " + e.message)
|
throw AuthenticationServiceException("Token validation failed. " + e.message)
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
package com.tarkvaratehnika.demobackend.security
|
||||||
|
|
||||||
|
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder
|
||||||
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity
|
||||||
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
|
||||||
|
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter
|
||||||
|
import org.springframework.security.config.http.SessionCreationPolicy
|
||||||
|
|
||||||
|
@EnableWebSecurity
|
||||||
|
class SecurityConfiguration : WebSecurityConfigurerAdapter() {
|
||||||
|
|
||||||
|
override fun configure(auth: AuthenticationManagerBuilder?) {
|
||||||
|
auth?.inMemoryAuthentication()?.withUser("justSomeUser")?.password("someBackdoorPasswordThisDoesntMatterItsADemo")
|
||||||
|
?.roles("USER")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun configure(http: HttpSecurity?) {
|
||||||
|
http?.sessionManagement()?.sessionCreationPolicy(SessionCreationPolicy.ALWAYS);
|
||||||
|
http?.authorizeRequests()?.antMatchers("/**")?.permitAll()
|
||||||
|
}
|
||||||
|
}
|
@ -18,7 +18,7 @@ class AuthenticationController {
|
|||||||
private val LOG = LoggerFactory.getLogger(AuthenticationController::class.java)
|
private val LOG = LoggerFactory.getLogger(AuthenticationController::class.java)
|
||||||
|
|
||||||
|
|
||||||
@PostMapping("authentication", consumes = [MediaType.APPLICATION_JSON_VALUE], produces = [MediaType.APPLICATION_JSON_VALUE])
|
@PostMapping("login", consumes = [MediaType.APPLICATION_JSON_VALUE], produces = [MediaType.APPLICATION_JSON_VALUE])
|
||||||
fun authenticate(@RequestBody body : String): Authentication {
|
fun authenticate(@RequestBody body : String): Authentication {
|
||||||
val parts = body.split("\"")
|
val parts = body.split("\"")
|
||||||
val authToken = AuthTokenDTO(parts[3], parts[7])
|
val authToken = AuthTokenDTO(parts[3], parts[7])
|
||||||
@ -29,9 +29,10 @@ class AuthenticationController {
|
|||||||
return AuthTokenDTOAuthenticationProvider.authenticate(auth)
|
return AuthTokenDTOAuthenticationProvider.authenticate(auth)
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("authentication", produces = [MediaType.APPLICATION_JSON_VALUE])
|
|
||||||
|
@GetMapping("login", produces = [MediaType.APPLICATION_JSON_VALUE])
|
||||||
fun getAuthenticated(headers: String) : Authentication? {
|
fun getAuthenticated(headers: String) : Authentication? {
|
||||||
val auth = WebEidAuthentication.fromChallenge(challenge)
|
val auth = WebEidAuthentication.fromChallenge("as")
|
||||||
if (auth == null) {
|
if (auth == null) {
|
||||||
throw ResponseStatusException(HttpStatus.FORBIDDEN, "Not allowed.")
|
throw ResponseStatusException(HttpStatus.FORBIDDEN, "Not allowed.")
|
||||||
}
|
}
|
||||||
|
@ -1 +1,2 @@
|
|||||||
|
server.servlet.session.cookie.http-only=false
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user