Keycloak仅保护特定路由[客户端]

时间:2018-06-28 12:03:02

标签: reactjs react-router openid-connect keycloak

我已经用我的ReactJS应用程序实现了keycloak身份验证。目前,我的所有路线都通过以下方式得到保护。

keyCloak.init({
    onLoad: 'login-required',
    checkLoginIframe: false
}).success(authenticated => {
    if (authenticated) {
        ReactDOM.render(Application, document.getElementById('root'));
    }
});

我仅在身份验证成功时才提供react应用程序。但是,现在我需要有一些公共路径,不需要任何用户可以检查的keycloak身份验证。有什么适当的方法可以实现这一目标吗?

2 个答案:

答案 0 :(得分:0)

您可以在Keycloak中创建不同的角色。在React应用程序中进行身份验证之后,将Keycloak对象传递到您的应用程序中,其中您的路由器具有路径。在那里,您可以检查用户拥有哪些权限,并基于该权限允许或不允许路由。

render() {
    let isAdmin = this.props.keycloak.hasRealmRole('admin');
    if(isAdmin){
        return (
            <div className="App">
                Router here
            </div>
        );
    }
    else{
        return (
            <div className="App">
                Router here
            </div>
        );
    }
}

另一个选择是不使用Keycloak封装整个应用程序,而仅使用您要保护的组件包装。

答案 1 :(得分:0)

安装@ react-keycloak /网络库

前提条件:keycloak-js 9.0.2或更高版本

npm install --save keycloak-js
npm install --save @react-keycloak/web

在项目的keycloak.js文件夹中创建一个src文件,其中包含以下内容,以根据需要设置Keycloak实例。

设置Keycloak实例

import Keycloak from 'keycloak-js'
const keycloakConfig = {
  url: 'http://localhost:8080/auth', 
  realm: 'Demo', 
  clientId: 'react-app'
}
const keycloak = new Keycloak(keycloakConfig);
export default keycloak

然后将您的应用包装在KeycloakProvider中,并将keycloak实例作为prop传递

import React from 'react';
import { KeycloakProvider } from '@react-keycloak/web'
import keycloak from './keycloak'
import AppRouter from './routes'

const App = () => {
  return (
    <KeycloakProvider keycloak={keycloak}>
      <AppRouter/>
    </KeycloakProvider>
  )
}

正如您在AppRouter组件中看到的,useKeycloak在没有第一参数的情况下被使用,因为我们不需要使用该keycloak实例对象。但是使用第二个initialized参数是因为PrivateRoute正在使用keycloak实例,并且keycloak对象需要在PrivateRoute初始化时可用,这意味着直到无法返回keycloak初始化的路由

import { useKeycloak } from '@react-keycloak/web';

import React from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';

import Menu from '../components/Menu';
import HomePage from '../pages/HomePage';
import { PrivateRoute } from '../utilities/PrivateRoute';
import ProtectedPage from '../pages/ProtectedPage';


export const AppRouter = () => {
    const [, initialized] = useKeycloak();
    if (!initialized) {
        return <h3>Loading ... !!!</h3>;
    }
    return (<>
        <Menu />
        <BrowserRouter>
            <Switch>
                <Route exact path="/" component={HomePage} />
                <PrivateRoute roles={['RealmAdmin']} path="/protected" component={ProtectedPage} />
            </Switch>
        </BrowserRouter>
    </>
    );
};

在项目的PrivateRoute.js文件夹中使用以下内容创建一个src/utilities文件。

import { useKeycloak } from '@react-keycloak/web';
import React from 'react';
import { Redirect, Route } from 'react-router-dom';


export function PrivateRoute({ component: Component, roles, ...rest }) {
  const [keycloak] = useKeycloak();

  const isAutherized = (roles) => {
    if (keycloak && roles) {
        return roles.some(r => {
            const realm =  keycloak.hasRealmRole(r);
            const resource = keycloak.hasResourceRole(r);
            return realm || resource;
        });
    }
    return false;
   }

   return (
      <Route
        {...rest}
        render={props => {
            return isAutherized(roles)
                ? <Component {...props} />
                : <Redirect to={{ pathname: '/', }} />
        }}
      />
    )
}

让我们看看如何使用Keycloak限制组件/功能。

import { useKeycloak } from '@react-keycloak/web';




    export default function AuthorizedFunction(roles) {
        const [keycloak, initialized] = useKeycloak();

        const isAutherized = () => {
            if (keycloak && roles) {
                return roles.some(r => {
                    const realm =  keycloak.hasRealmRole(r);
                    const resource = keycloak.hasResourceRole(r);
                    return realm || resource;
                });
            }
            return false;
        }

        return isAutherized();
    }

enter image description here

此外,还有另一种限制花药包装的成分,如下例所示。 (带有包装器组件)

https://medium.com/@cagline/authenticate-and-authorize-react-routes-component-with-keycloak-666e85662636