Policy in freeradius isnt running - freeradius

Im building a freeradius server for authenticate.
I have a problem with policy.conf:
The policy.conf was loaded in radius.conf as $INCLUDE policy.conf but the content of this file didn't work.
I tested by login with 'test' user but it didn't reject. Can someone help me about this, thanks very much.
policy {
#
# Forbid all EAP types.
#
if (User-Name == 'test'){
reject
}
forbid_eap {
if (EAP-Message) {
reject
}
}
#
# Forbid all non-EAP types outside of an EAP tunnel.
#
permit_only_eap {
if (!EAP-Message) {
# We MAY be inside of a TTLS tunnel.
# PEAP and EAP-FAST require EAP inside of
# the tunnel, so this check is OK.
# If so, then there MUST be an outer EAP message.
if (!"%{outer.request:EAP-Message}") {
reject
}
}
}
#
# Forbid all attempts to login via realms.
#
deny_realms {
if (User-Name =~ /#|\\/) {
reject
}
}
}

First you need to give your policy a name (like the other policies in the policy section).
policy {
reject_test {
if (User-Name == 'test'){
reject
}
}
}
You then need to list the policy in one of the sections (authorize, authenticate, post-auth etc...) of one of the virtual servers.
See the concepts page in the FreeRADIUS wiki for some basic details about which sections get run and where.
If you're using a stock configuration you'll likely need to edit raddb/sites-available/default.
In this case you probably want to add your policy to the authorize section.
authorize {
reject_test
...
}
You don't actually need to define policies in order to run use the policy language, you could insert your condition directly into the authorize section.
authorize {
if (User-Name == 'test'){
reject
}
}

Related

FreeRadius - Group NAS Clients

Have spent many hours searching and no luck so far,
I am looking for a clean way to group devices in freeradius for policy reference.
I tried creating a custom dictionary attribute (Device-Group) and applying it under the client definition
client cisco_device {
ipaddr = 1.2.3.4
Device-Group = Cisco_ISRs
}
and then in the authorization section:
if (&Device-Group == 'Cisco_ISRs') {
&cisco-avpair := 'priv-lvl 15'
}
But looking at the debug, custom dictionary attributes dont apply with clients.
The only alternative I have so far relies on naming conventions. i.e.
client cisco_site1 {
#blah blah
}
authorize {
if (&Client-Shortname =~ '/^cisco_./') {
#blah blah
}
}
but it would be nicer to have it in defined groups.
Any insight or ideas would be greatly appreciated.

Auth0 Social Login Role Assignment

At my current project, we are using Auth0 as our Identity Provider. The current architecture is just a ReactJS app supported by a couple of APIs. Each API requires different combinations of Authorization Scopes, but basically they will require Customer Role, Provider Role or any authenticated user.
We were using Username-Password-Authentication so far and now we are integrating Social logins (such as Facebook, Google and Apple).
In order to achieve so, we are using Authorization Code flow, so the BE constructs the Authorize URL (including Callback URL, scopes, etc) that the FE then uses. After the user has authenticated against the Social Provider, the Callback URL is called, we exchange the code for an access_token that is ultimately returned to the FE. So far so good.
https://{domain}.auth0.com/authorize?
response_type=code&
client_id={clientId}&
audience={audience}&
connection=facebook&
state={ramdom_value}&
redirect_uri={callbackUrl}&
scope=offline_access openid scope:customer
And here is where some issues arise.
Firstly, after exchanging the Authentication Code for an access_token, the token does not include the scopes in it, so the user cannot access the APIs. I had to create a custom rule that adds the Customer role, like this:
function (user, context, callback) {
var count = context.stats && context.stats.loginsCount ? context.stats.loginsCount : 0;
if (count > 1 || (context.connection !== 'facebook' && context.connection !== 'google-oauth2' && context.connection !== 'apple')) {
return callback(null, user, context);
}
var ManagementClient = require('auth0#2.17.0').ManagementClient;
var management = new ManagementClient({
token: auth0.accessToken,
domain: auth0.domain
});
management.assignRolestoUser(
{ id : user.user_id},
{ "roles" :["rol_Msm9ykmstuK09r9s"]},
function (err) {
if (err) {
callback(err);
} else {
callback(null, user, context);
}
}
);
}
I don't really understand why I need to create the rule in order to get a valid access_token.
Secondly, there are two possible roles for users, Customers and Providers. For now, we are only allowing customers to use Social Logins, but eventually we will need to support also Providers. There is no way for us to detect what kind of user is actually logging in within that rule.
So my question here would be how to solve it.
My final goal is to allow users (both Customers and Providers) to log in using Social Connections and have each of them with the roles they really require. Of course, I need to get a valid access_token so that users can then interact with our APIs.
Any thoughts or comments? What am I missing?
I came up with an elegant solution after all.
The approach I took was:
Create a Custom Rule that assigns both roles (Customer and Provider) only and only if:
1.1. This is the first login for this user
1.2. The connection type is either facebook or google-oauth2 or apple
When creating the URL for login, include only the scopes required based on the user role required. In addition, the callback url will include the user role in it, e.g. https://server/{platform}/callback/{role}
In the callback endpoint, remove the roles that are not required using the Auth0 Management API /api/v2/users/{id}/roles
This solution is a bit tricky, but works with relatively small coding and effort.

FreeRadius filter_username

I need to adjust the filter to a radius in order to allow a connection only with the username which contains the word "test".
Set up the block:
filter_private {
if (User-Name =~ /^(?!test).*$/) {
update reply {
Reply-Message += "Rejected: Username rejected, because not test"
}
reject
}
}
But it allows absolutely any username.
Based on the documentation, I think you need to negate the logic:
if (User-Name !~ /^(?!test).*$/) {
# etc.
}
Also, the regex above probably (depending on your local regex engine) allows usernames starting with test (due to ^) not any username containing test. For the latter, you would need to change the logic to be:
if (User-Name !~ /.*test.*/) {
# etc.
}

Firebase Security - Shared Data

I am getting confused about Firebase Security. Here why...
For example; I have the following database:
clients: {
$key: {
//client data
}
}
trainer: {
$key: {
//trainer data
}
}
I need a client to be able to see their own information. I need a trainer to be able to see the information of all their clients, but not other trainers.
So client A, B and C can see their personal, private data. But Trainer A can only see client A and B's details (he doesn't train C).
The problem I run into is that you can't seem to request for example all clients, but only return the ones that checkout with security rules. As the docs state, if one in the list returns false, the whole bunch does.
How can I create the correct structure and security rules?
You should impliment something like adding clients to trainer as friend. Create a node sharedwith which contains trainer as child and trainer will contains A & B clients key and their data .
Similar to examples in the Firebase docs (https://firebase.google.com/docs/database/security/user-security), this might work for you.
I think at a minimum your structure could benefit from having a direct key tie between client and trainer. Something like
clients: {
clientA: {
trainerKey: "trainerA"
}
}
trainers: {
trainerA: {
clients: { clientA: true, clientB: true }
}
}
Security Rules - edited to include user
"clients": {
".read": "auth !== null && (root.child('trainers/' + $trainerKey + '/clients').child($uid).exists() || auth.uid == $uid")
}
This a) checks that a user is authenticated and b) looks to see if the client is in the list of clients for the trainer OR whether this is the client.
This is untested, but hopefully gets you where you're trying to go. I'm also making the assumption that your clients IDs are the same as their auth ID.

Stoping saved request that triggered the login, always redirect to `/`

I have a web application that contains a REST api that is interacted with by the client application that lives at /. When a user session times out and the client js application makes a request to the REST api, that request will trigger a login event. Once the user logs in the user is then taken to the REST api endpoint which just displays a JSON response. I would like to hard wire the login page to always redirect to /.
Edit 1: I'm using spring-security-core plugin with the openid plugin as well and grails 2.0.4.
Edit 2: So I managed to get a solution working, however its a bit crude and I would like to know if there is a more elegant solution out there.
I created a simple filter in grails-app/conf/LoginRedirectFilters.groovy:
class RedirectLoginFilters {
def filters = {
redirectAfterLogin (uri: '/api/*') {
before = {
if (session["LOGGING_IN"])
redirect uri: "/"
}
after = {
if (session["LOGGING_IN"])
session["LOGGING_IN"] = false
}
}
}
}
And in my auth function inside of OpenIdController.groovy I added the session flag LOGGING_IN:
def auth = {
def config = SpringSecurityUtils.securityConfig
if (springSecurityService.isLoggedIn()) {
redirect uri: config.successHandler.defaultTargetUrl
return
}
session["LOGGING_IN"] = true
.
.
.
This is working properly by only checking if the LOGGING_IN flag is true when an api endpoint is called, and it also kills the flag after one request so it won't interfere with subsequent client api calls. I realize this is pretty convoluted, so if there is a better solution please let me know, thanks!
Why can't you use the same "springSecurityService.isLoggedIn()" inside your filter as well? I'm pretty sure that works as well.
I think I'm misunderstanding exactly what you want to achieve, but if you always want to redirect to '/' after a successful login, just set these properties in your Config.groovy:
grails.plugins.springsecurity.successHandler.alwaysUseDefault = true
grails.plugins.springsecurity.successHandler.defaultTargetUrl = "/"
If you want different behaviour to this, you'll have to flesh out your question.

Resources