Loggin in to VueJS App via Spring Security - spring

I am building a webapp with a Spring Backend and a VueJS frontend.
I am trying to secure my app via Spring Security but i noticed some major problems.
First I tried to secure the app with the standard spring security login mechanism but due to the fact that the vue app runns on a different port than my spring app
.authorizeRequests()
.antMatchers("/","/css/**","/login.html","/register.html","/index.html")
.permitAll().and().authorizeRequests().antMatchers("/console/**").permitAll()
.antMatchers("/application.html","**localhost:8080**").hasAnyRole("USER","ADMIN")
.antMatchers("/admin_application.html").hasAnyRole("ADMIN")
[...]
the tomcat is not listening on the vue port (:8080 in this case) so it just can't see if someone is connecting on this port.
I also looked at JWT and OAuth but due to the fact that i have a tight time budget it was too much to implement for me.
Is there a possible way to use the Spring Security mechanism for securing the frontend? If so, do you have any resource I can possible look at?
Kind regards

I setted the forwarding URI to a html document I created in my Spring and attached
<meta http-equiv="refresh" content="0; url=http://localhost:8080/" />
to it so I have a link to my vue app from my spring security login form.
Just have to close my Vue port via nginx (or so) and then i should be good to go :)

Had to reimplement this in vue,
doing login with vue, authenticating against my spring security and setting a store variable in vuex store
router.js:
beforeEnter: (to, from, next) => {
if (store.state.loggedIn == false) {
next(false);
} else {
next();
}
}
main.js:
mutations: {
loginSuccess(state){
state.loggedIn = true
},
logoutSuccess(state){
state.loggedIn = false
}
Login method
methods: {
performLogin() {
let formData = new FormData();
formData.set("username", this.username);
formData.set("password", this.password);
Axios.post('http://localhost:8181/perform_login', formData,{headers: {'Content-Type': 'application/x-www-form-urlencoded'}})
.then((result) => {
this.$store.commit('loginSuccess')
window.location = '#/dashboard'
})
.catch((error) => {
console.error(error)
})
},
may this helps one of you!

Related

Nuxt Auth + socialite manual login

I am trying to use the Nuxt Auth module and socialite for social logins. I have an API in Laravel 8 and a client in NuxtJS.
I am wondering if someone could tell me:
If my logic here is ok?
How to manually log user with nuxt auth (manually set token and user)?
So currently here is my flow for social logins:
Click on login with google makes an API call to my backend where I get redirect URL from socialite to google.
My frontend redirects me to the google login page, then back to my frontend app after I picked the account.
I send the google code to the backend to callback endpoint for socialite which then grabs me the google user. In same place after I deal with users in my app I am returning the token which I create by doing return $this->okResponse(['token' => $nativeUser->createToken('social-login')->accessToken]);
At this point I am back in my front end with the token which then I am trying to set this.$auth.setUserToken(response.data.token) which apparently does not equal logging the user in. So it looks like this:
mounted() {
this.$axios.get(`login/social/google/callback`, {params: {code: this.$route.query.code}}).then(response => {
console.log(response)
// this.$auth.strategy.token.set(response.data.token)
this.$auth.setUserToken(response.data.token)
if (this.$auth.loggedIn) {
console.log('I am logged in!')
} else {
console.log('I am NOT logged in!', this.$auth)
}
})
}
I am not logged in. Do I have to manually set loggedIn, 'User' and token? Or this is just madness? The only other thing I see here as a solution is my own custom strategy but this seems like total overkill.
Not sure if this is the best way but I ended up doing something like this.
mounted() {
this.$axios.get(`login/social/google/callback`, {params: {code: this.$route.query.code}}).then(response => {
this.$auth.setUserToken(response.data.token)
this.$auth.setUser(response.data.user)
if (this.$auth.loggedIn) {
console.log('I am logged in!')
} else {
console.log('I am NOT logged in!', this.$auth)
}
})
}
This seems to be working ok.

How to use Auth::check or Auth::user between different domains?

I've got a question regarding Laravel framework (vers. 5.2) and the authentication. I have 2 domains which represent a software. let's call them https://azure.mydomain.com and https://azuresoftware.mydomain.com.
The Laravel application is hosted on the domain https://azuresoftware.mydomain.com. https://azure.mydomain.com is just a CMS framework which is providing some information about the website.
Now I want to display different menus, if the user is logged in or not on https://azure.mydomain.com. I thought, I can do a fetch request to https://azuresoftware.mydomain.com/ and use the Laravel methods Auth::check() to check if the user is already logged in or not. I know that this is a CORS fetch request, but this is not the issue. I've allowed in the IIS webserver requests from https://azure.mydomain.com. The request works fine and also just a simple request. But actually Auth::check() is always returning false, even when I'm logged in on the software side.
This is my code so far:
<script>
fetch('https://azuresoftware.mydomain.com/checkLogin', {
method: 'GET',
headers: {
'Content-Type': 'text/plain'
}
})
.then(function(res) {
return res.json()
})
.then(function(data) {
if(data.isLoggedIn) {
// do some stuff...
}
else
{
// do some other stuff...
}
});
</script>
routes.php:
Route::group(['middleware' => 'web'], function () {
...
Route::get('checkLogin', function() {
return json_encode(['isLoggedIn'=>\Auth::check()]);
});
...
I'm sure, I forgot something essential, why it is not working this way.
This is due to the fact that AJAX calls only send cookies if the url you're calling is on the same domain as your calling script.
See Cross domain POST request is not sending cookie Ajax Jquery for more information.

Nuxt Axios Dynamic url

I manage to learn nuxt by using following tutorial
https://scotch.io/tutorials/implementing-authentication-in-nuxtjs-app
In the tutorial, it show that
axios: {
baseURL: 'http://127.0.0.1:3000/api'
},
it is point to localhost, it is not a problem for my development,
but when come to deployment, how do I change the URL based on the browser URL,
if the system use in LAN, it will be 192.168.8.1:3000/api
if the system use at outside, it will be example.com:3000/api
On the other hand, Currently i using adonuxt (adonis + nuxt), both listen on same port (3000).
In future, I might separate it to server(3333) and client(3000)
Therefore the api links will be
localhost:3333/api
192.168.8.1:3333/api
example.com:3333/api
How do I achieve dynamic api url based on browser and switch port?
You don't need baseURL in nuxt.config.js.
Create a plugins/axios.js file first (Look here) and write like this.
export default function({ $axios }) {
if (process.client) {
const protocol = window.location.protocol
const hostname = window.location.hostname
const port = 8000
const url = `${protocol}//${hostname}:${port}`
$axios.defaults.baseURL = url
}
A late contribution, but this question and answers were helpful for getting to this more concise approach. I've tested it for localhost and deploying to a branch url at Netlify. Tested only with Windows Chrome.
In client mode, windows.location.origin contains what we need for the baseURL.
# /plugins/axios-host.js
export default function ({$axios}) {
if (process.client) {
$axios.defaults.baseURL = window.location.origin
}
}
Add the plugin to nuxt.config.js.
# /nuxt.config.js
...
plugins: [
...,
"~/plugins/axios-host.js",
],
...
This question is a year and a half old now, but I wanted to answer the second part for anyone that would find it helpful, which is doing it on the server-side.
I stored a reference to the server URL that I wanted to call as a Cookie so that the server can determine which URL to use as well. I use cookie-universal-nuxt and just do something simple like $cookies.set('api-server', 'some-server') and then pull the cookie value with $cookies.get('api-server') .. map that cookie value to a URL then you can do something like this using an Axios interceptor:
// plguins/axios.js
const axiosPlugin = ({ store, app: { $axios, $cookies } }) => {
$axios.onRequest ((config) => {
const server = $cookies.get('api-server')
if (server && server === 'some-server') {
config.baseURL = 'https://some-server.com'
}
return config
})
}
Of course you could also store the URL in the cookie itself, but it's probably best to have a whitelist of allowed URLs.
Don't forget to enable the plugin as well.
// nuxt.config.js
plugins: [
'~/plugins/axios',
This covers both the client-side and server-side since the cookie is "universal"

How can I configure web api's http configuration in bit framework based apps?

I've configured web api using following code:
dependencyManager.RegisterWebApiMiddleware(webApiDependencyManager =>
{
webApiDependencyManager.RegisterWebApiMiddlewareUsingDefaultConfiguration();
});
How can I customize http configuration?
As you can see in https://docs.bit-framework.com/docs/bit-server-side/web-api.html#getting-started
You can write:
dependencyManager.RegisterWebApiMiddleware(webApiDependencyManager =>
{
webApiDependencyManager.RegisterWebApiMiddlewareUsingDefaultConfiguration();
webApiDependencyManager.RegisterGlobalWebApiCustomizerUsing(httpConfiguration =>
{
// You've access to web api's http configuration here
});
});

Google authentication with Angular2 and ASP.NET core Web API app

I'm creating an web application in Angular2 and i'd like to use Google for the user to login and use the application. Basically, once the user is logged in with Google, he will navigate in the site and make some AJAX call via Angular to the ASP.NET Core Web API.
In my mind, I though that all these calls should contain a JWT (issued by Google) and the ASP.NET Core Web Api would validate the token and then process the request if the token is valid. Simple enough... However, I'm struggling to find out how this could be achieved. All I found is posts talking about how to login via Google in order to use Google APIs. In my case, I don't need any Google API but the login one.
So far, I have this:
export class GoogleAuthenticationService {
private auth: any;
constructor(private userService: UserService) {
}
public bindLoginButton(element: any) {
this.ensureApiIsLoaded().then(() => {
this.auth.attachClickHandler(element, {}, (user) => {
let profile = user.getBasicProfile();
this.userService.set(profile.getName(), profile.getEmail(), user.getAuthResponse().id_token, AuthenticationType.Google);
});
});
}
// TODO: Better type definition of the promise
private ensureApiIsLoaded() {
return new Promise((resolve, reject) => {
gapi.load('auth2', () => {
this.auth = gapi.auth2.init({
client_id: "CLIENT_ID",
cookiepolicy: 'single_host_origin',
scope: 'profile email'
});
resolve();
});
});
}
}
Basically, I'm just initializing "gapi" with my client ID, then I define some properties in the "UserService". This works pretty well. Moreover, I'm using the value returned by user.getAuthResponse().id_token for every call to my web service (I did this following this article). The next step was to try and validate the token in C# (like the sample in Java) but I didn't find any valid resources talking about that and the class used in the Java code does not exists in C#...
Is it that complicated or am I just on the wrong path and this is totally not how the web application is supposed to work. Could someone give me some pointers about this scenario that is, according to me, quite common.

Resources