Call to undefined method Illuminate\Database\Query\Builder::createToken(), - laravel-passport

I have API Laravel5 project using laravel passport & oauth.How to fix the above error.
I can't create API Tocken..
public function login(){
if(Auth::attempt(['email' => request('email'), 'password' => request('password')])){
$user = Auth::user();
$success['token'] = $user->createToken('MyApp')->accessToken;
return response()->json(['success' => $success], $this->successStatus);
}
else{
return response()->json(['error'=>'Unauthorised'], 401);
}
}

I suspect you haven't added use HasApiTokens in User model.
Refer configuration instructions on: https://laravel.com/docs/5.6/passport

Related

How to access jwt after login using msal.js adb2c

After logging in using the MsalAuthenticationTemplate InteractionType.Redirect, how do I get the JWT returned after successful authentication? It does not seem to be included in the msal instance.
import { MsalProvider, MsalAuthenticationTemplate, useMsal, useAccount } from "#azure/msal-react";
const { instance } = useMsal();
You should call acquireTokenSilent each time you need an access token. You can read more in our getting started doc and also review the msal-react-samples
Another way of getting the idToken(JWT) after successful login is to hook into the addEventCallback and check for EventType.LOGIN_SUCCESS.
const callbackId = instance.addEventCallback(message => {
if (message.eventType === EventType.LOGIN_SUCCESS) {
const { payload } = message;
// Get idToken(JWT) from the payload.
console.log(payload.idToken);
}
})
https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-browser/docs/events.md

Loopback 4 authentication metadata options undefined

I have created a simple jwt auth application the same way its displayed here: https://github.com/raymondfeng/loopback4-example-auth0
The authentication part is working properly but the authorization does not work as expected.
I decorated my controller with following function and added a scope.
#authenticate({strategy: 'auth0-jwt', options: {scopes: ['greet']}})
In my authentication strategy I´m checking the scope via the AuthenticationMetadata class.
import {AuthenticationBindings, AuthenticationMetadata, AuthenticationStrategy} from '#loopback/authentication';
import {inject} from '#loopback/core';
import {ExpressRequestHandler, Request, Response, RestBindings} from '#loopback/rest';
import {UserProfile} from '#loopback/security';
import {JWT_SERVICE} from './types';
const jwtAuthz = require('express-jwt-authz');
export class JWTAuthenticationStrategy implements AuthenticationStrategy {
name = 'auth0-jwt';
constructor(
#inject(RestBindings.Http.RESPONSE)
private response: Response,
#inject(AuthenticationBindings.METADATA)
private metadata: AuthenticationMetadata,
#inject(JWT_SERVICE)
private jwtCheck: ExpressRequestHandler,
) {}
async authenticate(request: Request): Promise<UserProfile | undefined> {
return new Promise<UserProfile | undefined>((resolve, reject) => {
this.jwtCheck(request, this.response, (err: unknown) => {
if (err) {
console.error(err);
reject(err);
return;
}
console.log(this.metadata.options);
// If the `#authenticate` requires `scopes` check
if (this.metadata.options?.scopes) {
jwtAuthz(this.metadata.options!.scopes, {failWithError: true})(request, this.response, (err2?: Error) => {
if (err2) {
console.error(err2);
reject(err2);
return;
}
// eslint-disable-next-line #typescript-eslint/no-explicit-any
resolve((request as any).user);
});
} else {
// eslint-disable-next-line #typescript-eslint/no-explicit-any
resolve((request as any).user);
}
});
});
}
}
When trying to access
this.metadata.options
I´m always getting an undefined back.
How can I achieve to get the options and the scope out of metadata?
Thanks
For Loopback Authorization your class needs to implement the Provider<Authorizer> interface. In that interface it defines the 2 functions you need to implement
#injectable({scope: BindingScope.TRANSIENT})
class AuthorizationService implements Provider<Authorizer>{
value (): Authorizer {
return this.authorize.bind(this);
}
async authorize (
context: AuthorizationContext,
metadata: AuthorizationMetadata,
) {
// TODO implement authorization
}
}
The authorization metadata will be injected by loopback into that function automatically after you bind it with an AuthorizationTags.Authorizer
If you are having problems implementing Authentication then read my step by step guide on how we implemented Loopback Authentication using Firebase. That should be able to help you with the core ideas to get Authentication running.

No sign-out authentication handler is registered for the scheme 'Identity.TwoFactorUserId'

ASP.NET Core 2.2 web app using code migrated from full fat MVC app.
My AccountController contains this simple code for its Logout route.
await this.SignInManager.SignOutAsync();
return this.RedirectToAction(nameof(Landing.HomeController.Index), "Home");
But this gives.
No sign-out authentication handler is registered for the scheme 'Identity.TwoFactorUserId'.
Pretty confusing given that I've never mentioned 2FA in my code, and Google login is working.
serviceCollection
.AddIdentityCore<MyUser>(identityOptions =>
{
identityOptions.SignIn.RequireConfirmedEmail = false;
})
.AddUserStore<MyUserStore>()
.AddSignInManager<SignInManager<MyUser>>();
serviceCollection.AddAuthentication(IdentityConstants.ApplicationScheme)
.AddCookie(IdentityConstants.ApplicationScheme, options =>
{
options.SlidingExpiration = true;
})
.AddGoogle(googleOptions =>
{
this.Configuration.Bind("OAuth2:Providers:Google", googleOptions);
googleOptions.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "sub", "string");
})
.AddExternalCookie();
As a complement to #Luke's answer:
The reason why SignInManager::SignOutAsync() throws is this method will also sign out the TwoFactorUserIdScheme behind the scenes:
public virtual async Task SignOutAsync()
{
await Context.SignOutAsync(IdentityConstants.ApplicationScheme);
await Context.SignOutAsync(IdentityConstants.ExternalScheme);
await Context.SignOutAsync(IdentityConstants.TwoFactorUserIdScheme);
}
(See source code)
Typically, these tree authentication schemes are registered automatically by AddIdentity<TUser, TRole>():
public static IdentityBuilder AddIdentity<TUser, TRole>(
this IServiceCollection services,
Action<IdentityOptions> setupAction)
{
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = IdentityConstants.ApplicationScheme;
options.DefaultChallengeScheme = IdentityConstants.ApplicationScheme;
options.DefaultSignInScheme = IdentityConstants.ExternalScheme;
})
...
.AddCookie(IdentityConstants.TwoFactorUserIdScheme, o =>
{
o.Cookie.Name = IdentityConstants.TwoFactorUserIdScheme;
o.ExpireTimeSpan = TimeSpan.FromMinutes(5);
});
... // other services
}
(See source code )
However, you added the Identity services by AddIdentityCore<>() instead of the AddIdentity<>().
Because the AddIdentityCore<>() doesn't register a TwoFactorUserIdScheme scheme (see source code) automatically, there's no associated CookieAuthenticationHandler for TwoFactorUserIdScheme. As a result, it throws.
How to solve
In order to work with SignInManager.SignOutAsync(), according to above description, we need ensure a <scheme>-<handler> map has been registed for TwoFactorUserIdScheme .
So I change your code as below, now it works fine for me:
serviceCollection.AddAuthentication(IdentityConstants.ApplicationScheme)
.AddCookie(IdentityConstants.ApplicationScheme, options =>
{
options.SlidingExpiration = true;
})
.AddCookie(IdentityConstants.TwoFactorUserIdScheme, o =>
{
o.Cookie.Name = IdentityConstants.TwoFactorUserIdScheme;
o.ExpireTimeSpan = TimeSpan.FromMinutes(5);
})
.AddGoogle(googleOptions =>
{
this.Configuration.Bind("OAuth2:Providers:Google", googleOptions);
googleOptions.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "sub", "string");
})
.AddExternalCookie();
Also you can create your own SignInManager<MyUser> and override sign out as you need
public class CustomSignInManager : SignInManager<MyUser>
{
public override async Task SignOutAsync()
{
await Context.SignOutAsync(IdentityConstants.ApplicationScheme);
await Context.SignOutAsync(GoogleDefaults.AuthenticationScheme);
}
}
Then change AddSignInManager<SignInManager<MyUser>>() to AddSignInManager<CustomSignInManager>() in your Startup class
serviceCollection
.AddIdentityCore<MyUser>(identityOptions =>
{
identityOptions.SignIn.RequireConfirmedEmail = false;
})
.AddUserStore<MyUserStore>()
.AddSignInManager<CustomSignInManager>();
Do not use the SignOutAsync method on a SignInManager<T> you've injected into the controller. Instead, use the method on the HttpContext which takes a scheme argument. I don't know why.
Below code works for me , use the same AuthenticationScheme that you use while "AddAuthentication" in startup.cs
[HttpGet("signout")]
[AllowAnonymous]
public async Task signout()
{
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
var prop = new AuthenticationProperties
{
RedirectUri = "/logout-complete"
};
// after signout this will redirect to your provided target
await HttpContext.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme, prop);
}
[HttpGet("logout-complete")]
[AllowAnonymous]
public string logoutComplete()
{
return "logout-complete";
}
I agree with itminus reply, We would get an error because in .net core 3.0 if we use AddIdentityCore<>() instead of AddIdentity<>() we would get an error. But when upgrading to .net 7.0 if we again use AddIdentityCore<>() instead of AddIdentity<>() we would get the same error for Identity.TwoFactorRememberMeScheme as well that I am faced with after upgrading. For SignInManager we require Identity.TwoFactorRememberMeScheme as well otherwise we get an error.
The solution which I applied in mine .net 7.0 project is:
Instead of adding every scheme and handler by yourself, we can just use
services.AddAuthentication().AddIdentityCookies();
This will add all the schemes handlers for you and at the time of signout we need to should use below:
await HttpContext.SignOutAsync(IdentityConstants.ApplicationScheme);
await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
await HttpContext.SignOutAsync(IdentityConstants.TwoFactorUserIdScheme);

Unable to get the MSI credentials with NodeJs

I am working with the NodeJs Azure Function V2 and I want to get the secret from Key-Vault.
I tried with following reference. Here's a link.
I am using ms-rest-azure NPM library package.
My code as follows:
function getKeyVaultCredentials(){
return msRestAzure.loginWithAppServiceMSI({resource: "https://my-keyvault-DNS-url.vault.azure.net",msiEndpoint: process.env["MSI_ENDPOINT"],msiSecret:process.env["MSI_SECRET"]});
}
function getKeyVaultSecret(credentials) {
var keyVaultClient = new KeyVault.KeyVaultClient(credentials);
return keyVaultClient.getSecret("https://my-keyvault-DNS-url.vault.azure.net", 'secret', "mySecretName");
}
getKeyVaultCredentials().then(
getKeyVaultSecret
).then(function (secret){
console.log(`Your secret value is: ${secret.value}.`);
}).catch(function (err) {
throw (err);
});
The function call executed successfully but never getting the credential.
Note :
I have enabled the MSI identity and given access to kevault for that Azure function.
The error I am getting is as follows:
MSI: Failed to retrieve a token from "http://127.0.0.1:410056/MSI/token/?resource=https://my-keyvault-DNS-url.vault.azure.net&api-version=2017-09-01" with an error: {"ExceptionMessage":"AADSTS500011: The resource principal named https://my-keyvault-DNS-url.vault.azure.net was not found in the tenant named 6620834b-d11e-44cb-9931-2e08b6ee81cc00. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You might have sent your authentication request to the wrong tenant.\r\nTrace ID: 1f25ac6c-01e0-40d8-8146-269f22d49f001\r\nCorrelation ID: 4beede0c-2e83-4bcc-944d-ba4e8ec2c6834\r\nTimestamp: 2019-03-29 02:54:40Z","ErrorCode":"invalid_resource","ServiceErrorCodes":["500011"],"StatusCode":400,"Message":null,"CorrelationId":"e6e8108d-e605-456b-8fb6-473962dcd5d678"}
I might doing some silly/blunder - please help!!
There are some subtle fixes that your code needs
resource should be set to https://vault.azure.net. This basically has to be the resource in general, not your instance as such.
The method is actually getSecret('<KEYVAULT_URI>', '<SECRET_NAME>', '<SECRET_VERSION>')
Here is how your code should look like at the end
function getKeyVaultCredentials() {
return msRestAzure.loginWithAppServiceMSI({
resource: 'https://vault.azure.net'
});
}
function getKeyVaultSecret(credentials) {
var keyVaultClient = new KeyVault.KeyVaultClient(credentials);
return keyVaultClient.getSecret(
'https://my-keyvault-DNS-url.vault.azure.net',
'mySecretName',
''
);
}
getKeyVaultCredentials()
.then(getKeyVaultSecret)
.then(function(secret) {
console.log(`Your secret value is: ${secret.value}.`);
})
.catch(function(err) {
throw err;
});

Loopback Context is found null in model beforeCreate when using Mocha

I have a model that access context object (to get currentUser) in beforeCreate.
myModel.beforeCreate = function(next, md) {
var Category = md.app.models.Category;
var ctx = loopback.getCurrentContext();
var currentUser = ctx && ctx.get('currentUser');
...
});
It works when I normally access it from explorer but when I try to access it using mocha in unit test
I get error because currentUser is not set.
So, when I try to set currentUser, I don't get context object in tests.
var ctx = loopback.getCurrentContext();
if (ctx) console.log("CTX exists");
here ctx is null.
Please suggest where I have gone wrong.
Cheers
Raj
I think if you use the loopback-testing module you'll have success more easily here. Specifically the givenLoggedInUser function creates a user for your test and logs that user in, creating a saved token as well.
var lt = require('loopback-testing');
var credentials = { email: 'user#example.com', password: 'pwd' }
lt.givenLoggedInUser(credentials, 'user');
it('should have a logged in user', function (done) {
if (loopback.getCurrentContext()) {
console.log("CTX exists", this.user);
}
});
This should also create the current context you need. Take a look at the rest middleware tests for more help here: https://github.com/strongloop/loopback/blob/master/test/rest.middleware.test.js#L128

Resources